Skip to content

Ability to pull files from GitHub, edit, and push back - #384

Draft
kentonv wants to merge 10 commits into
mainfrom
kenton/worktrees
Draft

Ability to pull files from GitHub, edit, and push back#384
kentonv wants to merge 10 commits into
mainfrom
kenton/worktrees

Conversation

@kentonv

@kentonv kentonv commented Aug 28, 2026

Copy link
Copy Markdown
Member

An agent can now mount a Git repo at a particular commit and do stuff with it.

This happens with NO containers, NO bash, NO git CLI. It's entirely JS/TS in a Durable Object

Specifically, the agent can create a "worktree", which appears to it kind of like a gadget that doesn't have any executable app. It's just code. The agent can read and edit files within the worktree using the same tool calls it uses to read and edit gadget code. A worktree is also a named binding in env -- the binding provides a JavaScript API to allow programmatic operations, including the ability to read, edit, grep, diff, make commits, etc.

The GitHub gatekeeper now makes commits visible in its API. Any time the gatekeeper tells the caller about a commit, it lets the Overseer know about the commit ID. If the agent subsequently tries to mount that commit, the Overseer will pull it from the gatekeeper. Pulls are shallow / lazy and populate the same local git storage used for gadget code.

The GitHub gatekeeper also now supports pushing commits and creating pull requests from them.

The plan file in plans/worktrees.ts contains a more complete explanation and implementation plain which the remaining commits follow.

This pull request was created entirely by my Cloudflare OS agent: kentonv/lanparty#10

TODO before merging:

  • Review and improve doc comments on all public APIs, especially agent-facing ones, remove AI turds.
  • Skim over the code some more, make sure there's no poor architectural decisions.
  • Activity in a worktree currently causes the "accept changes" dialog to appear in the UI, even though the worktree itself is not exposed in the UI at all. Need to decide how to fix this.
  • My agent tried to do env.WORKTREE.grep(".", pattern) and got an error because "." isn't recognized -- should special-case this.
  • My agent implied it didn't know the default branch for the repo -- verify this is in the API, or add it.
  • Verify GitHub APIs as designed actually match well with what the underlying REST API provides.

Devin Review
kentonv added 10 commits August 28, 2026 16:14
Claude was confused since it said it goes on interfaces, but it actually goes on implementations.
This was written out by my human hand to illustrate what I'm going for, before engaging the agent to write any plans.
Written by Fable with lots of guidance from me as well as no fewer than FIVE review passes by Sol, each of which came up with more actual legit issues to fix.
This implements commit 1 of plans/worktrees.md.

This introduces the new Gatekeeper APIs for interacting wit the git cache. They are not implemented yet, so workshop-backend fails to build at this point.

(gatekeeper-cloudflare is updated to avoid breaking its test. No other gatekeeper needed such an update.)
This is commit 2 from the plan in plans/worktrees.md.

This introduces the core new functionality underlying the git cache with remote provenance. The `gitObjectMetadata` table is introduced which tracks information about objects that may not yet be present locally, allowing them to be pulled on demand.
This implements commit 3 of plans/worktrees.md.

This introduces the actual concept of worktrees as a type of workpiece, along with agent tools for operating on them.
This implements commit 4 of plans/worktrees.md.

This introduces the Worktree binding API, accessible to agents via executeCode.
This implements commit 5 of plans/worktrees.md.

This extends the GitHub gatekeeper to allow querying refs and to advertise the commits it holds so that they can be mounted. However, actually pulling them is not implemented yet (next commit).
This implements commit 6 of plans/worktrees.md.

This commit implements support for pulling from GitHub, in order to fulfill requests to mount a worktree from commits advertised by the gatekeeper.
This implements commit 7 of plans/worktrees.md.

This completes the series by implementing the ability to push to GitHub, including opening a PR!
@github-actions github-actions Bot added workshop/frontend Changes to the Workshop frontend kernel Changes to the Workshop kernel gatekeeper Changes to a gatekeeper integration workshop/shared Changes to shared Workshop APIs labels Aug 28, 2026
@github-actions

Copy link
Copy Markdown

Preview: pr384-kenton-worktrees

https://pr384-kenton-worktrees-router.cloudflare-os-previews.workers.dev

Dashboard · deleted when this PR closes

@kentonv
kentonv marked this pull request as draft August 28, 2026 21:34

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review
@ask-bonk

ask-bonk Bot commented Aug 28, 2026

Copy link
Copy Markdown
  • High packages/workshop-backend/src/agent.ts:3049, worktree-session.ts:371: Commit prefixes resolve against workspace-global state without checking the chat’s bindings. An agent can access commits introduced by an unavailable private binding using only a four-hex prefix. Scope resolution to authorized chat sources or require a non-enumerable commit capability.

  • High packages/workshop-backend/src/git-codec.ts:355: An overlong size varint can overflow to NaN, bypassing both inflation limits and allowing a compressed bomb to exhaust memory. Reject non-safe integers while decoding.

  • High packages/workshop-backend/src/git-cache.ts:323, git-codec.ts:392: The 64 MiB limit applies only to compressed pack bytes and individual objects. Thousands of distinct, compressible sub-64 KiB blobs remain retained after inflation and can exceed Worker memory. Add aggregate inflated-byte and object-count limits.

  • High packages/gatekeeper-github/src/github.ts:3618: The gatekeeper persists the push as approved before the Workshop records completion. A crash in between leaves the Workshop action pending, but retries fail the state guard at line 3401, permanently stranding the action after the remote branch changed. Approved pushes must return idempotent success.

  • Medium packages/workshop-backend/src/overseer.ts:5201: Worktree loopbacks identify only the chat, not the execution. A stub retained by a gadget during one execution becomes valid again during a later execution for that chat and operates on the new turn. Include an execution nonce and verify session liveness.

  • Medium packages/gatekeeper-github/src/github.ts:3985, github.ts:4005: Pending-push simulation catches only 404, but GitHub returns 422 for unknown commit SHAs and refs. Consequently, getCommit() cannot simulate newly pushed commits or branches. The test fake currently masks this with a 404.

  • Medium packages/gatekeeper-github/src/github.ts:3897, github.ts:4467: listBranches() snapshots simulated branches. If the push is rejected before next(), the stale branch is returned and its unpushed commit is advertised as remotely available, corrupting pull provenance and later push marking.

  • Medium packages/workshop-backend/src/git-cache.ts:1036: Push pack generation materializes every loose object, every compressed chunk, and another concatenated copy for hashing, with no aggregate/output cap. A sufficiently large valid push can OOM before streaming begins.

github run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gatekeeper Changes to a gatekeeper integration kernel Changes to the Workshop kernel workshop/frontend Changes to the Workshop frontend workshop/shared Changes to shared Workshop APIs

1 participant