fix(desktop): shallow clone repositories for repo-less cloud tasks - #76903
Merged
Conversation
|
😎 Merged successfully - details. |
charlesvien
marked this pull request as ready for review
August 3, 2026 21:19
Contributor
Prompt To Fix All With AI### Issue 1
products/desktop/packages/agent/src/adapters/local-tools/tools/clone-repo.ts:135-136
**Existing branches remain stale**
When a retry, reconnected session, or later tool call requests a branch that already exists locally after its remote has advanced, `git checkout` succeeds and returns before the only fetch operation, causing the agent to edit stale code and potentially create a commit or pull request that omits newer remote changes.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "refactor(desktop): clone via execGit ins..." | Re-trigger Greptile |
Contributor
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 2 · PR risk: 0/10 |
charlesvien
approved these changes
Aug 4, 2026
Member
|
/trunk merge |
Contributor
🦔 ReviewHog reviewed this pull requestFound 0 must fix, 0 should fix, 3 consider. Published 3 findings (view the review). |
Contributor
|
ReviewHog Alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏 |
Contributor
There was a problem hiding this comment.
ReviewHog Report
Changes
Issues: 3 issues
Files (11)
products/desktop/packages/agent/src/adapters/claude/claude-agent.tsproducts/desktop/packages/agent/src/adapters/claude/tools.tsproducts/desktop/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.tsproducts/desktop/packages/agent/src/adapters/local-tools/tools/clone-repo.tsproducts/desktop/packages/agent/src/pi/repository-tools-extension.tsproducts/desktop/packages/agent/src/pi/rpc-client.tsproducts/desktop/packages/agent/src/pi/rpc-host.tsproducts/desktop/packages/agent/src/server/agent-server.tsproducts/desktop/packages/agent/src/server/pi-agent-server.tsproducts/desktop/packages/git/src/git-exec.tsproducts/desktop/packages/git/src/utils.ts
Repo-less cloud tasks discover and clone a repository at runtime. CloneSaga ran a plain `git clone`, so picking up a large monorepo pulled its full history and tags before any work started. - expose `list_repos` / `clone_repo` to repo-less Claude, Codex, and pi cloud sessions - clone with `--depth 1 --single-branch --no-tags`, authenticating via `http.extraHeader` so the token never lands in `origin` - tell the agent to use those tools and deepen history only when it needs to - auto-allow the repository setup tools in Auto mode Ported from PostHog/code#4051, which was open when the desktop app moved into this repo. Generated-By: PostHog Code Task-Id: 18ef3ffb-2064-465f-a2f8-496ba659e79a
clone_repo only ever runs inside agent-server, against a scratch checkout no one else touches, so CloneSaga's repo locking and rollback bookkeeping buy it nothing — and routing through simple-git meant opting out of that client's guard against GIT_CONFIG_* in the child env just to pass http.extraHeader auth. Adds execGit alongside execGh in @posthog/git and drives the clone, origin repair, and branch fetch through it. CloneSaga and createGitClient go back to their master state, leaving the desktop clone path untouched. Origin inspection now reads remote.origin.url rather than `remote get-url`, which resolves url.<base>.insteadOf and could mask a persisted credential. Generated-By: PostHog Code Task-Id: 18ef3ffb-2064-465f-a2f8-496ba659e79a
An unscoped `http.extraHeader` is attached to every HTTP remote git talks to. The missing-branch path fetches from whatever `origin` the existing checkout holds, and that origin was only rewritten when it carried embedded credentials, so a checkout retargeted at another host would have been handed the live token. Scopes the header to `https://github.com/`, verified against `git config --get-urlmatch`, and normalizes any origin that isn't the canonical clone URL rather than only the ones with credentials in them. Only this tool writes to `repos/<owner>/<repo>`, so a mismatch always means the remote was changed after the clone. Generated-By: PostHog Code Task-Id: 18ef3ffb-2064-465f-a2f8-496ba659e79a
charlesvien
force-pushed
the
posthog-code/shallow-clone-repoless-tasks
branch
from
August 5, 2026 00:47
5352106 to
542013d
Compare
Contributor
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
Member
|
/trunk merge |
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.
Problem
Repo-less cloud tasks discover and clone repositories at runtime through the
clone_repotool, which did a fullgit clone. On large repositories that pulls years of history and tags into every sandbox. Sandbox-init clones are already shallow; agent-initiated ones were not.Port of PostHog/code#4051, which went stale during the desktop migration. The
list_repos/clone_repotools came across but the shallow-clone half did not.Changes
clone_repoclones with--depth 1 --single-branch --no-tagsthrough a newexecGit(rawexecFile, next toexecGhin@posthog/git) instead of the simple-git clone saga. It fetches a missing branch into an existing shallow clone and normalizes a retargeted or credential-carrying origin before fetching.http.extraHeaderscoped tohttps://github.com/, so the token never lands in.git/configand is never sent to non-GitHub remotes.parseGithubUrlrejects dot segments and unsafe characters in owner/repo. scp-style inputs skip WHATWG dot-segment normalization, sogit@github.com:owner/..would otherwise collapse the clone target onto the whole scratch tree, which the failure-path cleanup then deletes.clone_repocalls for the same repo serialize per target path, so a racing duplicate can't delete an in-progress checkout from its failure path.list_repos/clone_repo. Multi-repo workspaces don't:channelModerequires norepositoryPathand no task repositories. The repo-less prompt tells the agent to deepen history in bounded steps only when a task needs older commits.How did you test this code?
Automated only, no manual app run:
clone-repo.test.tsdrives the real tool against real git with no network (a tempGIT_CONFIG_GLOBALmaps the GitHub URL to a local fixture). Covers the shallow/single-branch/no-tags shape, token absent from the checkout config, auth header scoping verified throughgit config --get-urlmatch, origin normalization, missing-branch fetch, traversal slugs rejected without touching the workspace, failed clones cleaned up and concurrent clones serialized.parseGithubUrlreject matrix gained the traversal and unsafe-character inputs.channelModestays off for multi-repo tasks.@posthog/agentand@posthog/gitsuites, typecheck and biome clean.Automatic notifications
Docs update
N/A
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Started from a Slack thread about monorepo clone times in repo-less sandboxes. Claude (PostHog Slack app) ported #4051, then dropped the original's
CloneSagaroute on review feedback: the saga layer is for the desktop app and going through it meant punching a hole in simple-git'sGIT_CONFIG_*env guard, so the clone moved to rawexecGit. A bot review flagged the unscoped auth header, which led to the github.com scoping and unconditional origin normalization. Claude Code then reviewed the branch and fixed what it found: path traversal in scp-style slugs reaching the failure-pathrm -rf, unserialized concurrent clones and missing permission-gating negative tests. Skills invoked: /writing-tests, /writing-code-comments.Created with PostHog from a Slack thread