Repository navigation
feat(workflow): add workspace branches - #1175
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
|
This PR's workspace worktrees start without the team's assets. The details are in my comment on #1080: #1080 (comment) In short:
I'd suggest giving the worktree the same delivery the Should this go in this PR or in a follow-up? |
A workflow worktree is created where the post-checkout hook does not run, so the step never received the team's skills, rules, agents, or MCP. Deliver them the same way a new worktree does, after the base agent files are restored and before the overlay is recorded, so they are not part of the step's commit. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Scope limitation: shallow history prevents resolving the requested three-dot diff. I reviewed the endpoint diff read-only; exact merge-base scope remains unverified. Findings
Testing |
Bring in model selection and agent records, and fix the review: keep hooks on the worktree, merge a dependency's recorded commit, include the step's own commits, and restore agent files without a dirty index or following a directory symlink. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep workspace branches working beside human-in-the-loop steps and the latest main: a step still merges the commit a dependency reported, and commands that share a checkout stay read-only. Co-authored-by: Cursor <cursoragent@cursor.com>
Commands with no workspace fail when they change the repository. These tests write those files only to show which checkout ran, so git ignores them. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
A step that needs a workflow now merges that workflow's child branches. Relative agent symlinks stay relative, a retry pushes commits an earlier attempt left unpublished, and an interactive Claude or Codex session resumes. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
A retry with no new commit still pushes when origin has other refs but not this branch's tip. Restoring agent files keeps the executable bit, and a symlink can replace the directory the base checkout put back. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
…dits A retry still pushes when origin has no remote-tracking refs and the commits live only on this branch. Restoring agent files keeps a chmod and a file written under a directory the branch had turned into a symlink. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
…ranches A prompt that leaves a conflicted agent file untouched no longer publishes the conflict markers. Nested workflows inherit needs, a continued fan child merges the item it waits for, and a workflow fan item reports its branch. Co-authored-by: Cursor <cursoragent@cursor.com>
Collect each item's child branch in one pass, so settling a skipped fan does not scan every step once per item. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
A prompt that exits before it runs puts the branch agent files back. An unresolved conflict is not committed, a resolution that matches the current tree still records the merge, and a fan item reports the child that finished last. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
…anch lists Restoring agent files does not follow a symlink the step just created. A modify/delete conflict stays unresolved until the step changes the file. An empty fan-out reports an empty branch list. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
|
Findings
Earlier Findings Testing |
…them Restore unmerged agent stages before the prompt runs, and remember conflicted paths so a later attempt cannot publish markers that were already staged. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
A prompt commit clears MERGE_HEAD before validation. Keep the conflicted paths until the resolution is accepted, so a later attempt cannot publish the markers. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
A command with no workspace can edit a file and commit it, leaving the worktree clean. Compare HEAD as well, and leave that commit in place. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
A cancelled workspace command left the base agent files in place, so the next attempt committed them over an earlier edit. A read-only command that only stages an existing edit now fails too. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
…rompt A read-only command can change the index blob while porcelain status stays mixed. An interactive prompt that sets workspace: read-only is checked the same way; other interactive prompts still keep the person's edits. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
A chmod on a file that is already dirty leaves porcelain status, staged blobs, contents, and HEAD unchanged. Compare the working-tree mode as well. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
Git quotes non-ASCII porcelain paths, and a symlink can change target without changing the file it names. Read status as raw bytes and hash the link target. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
Porcelain -z lists a rename's new path first. Conflict checks use NUL-delimited names so a quoted non-ASCII path is still rejected when markers remain. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings
Earlier Findings Testing |
Agent conflict paths from ls-files are NUL-delimited, so a non-ASCII name is restored instead of published as the base file. A read-only command that edits a file inside an already dirty submodule fails too. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Findings Earlier Findings Testing I reviewed the requested three-dot diff read-only against the base version’s review rules. I did not run, build, or install PR code. |
Closes #1080
Summary
for_eachbranches/results and session continuation across steps and passesTesting
npm run buildnpx tsc --noEmitnpm run lintnpx vitest run src/__tests__/workflow-workspace.test.ts src/__tests__/workflow-local-driver.test.ts --reporter=dot(38 passed before final review fixes; focused workspace suite rerun below)npx vitest run src/__tests__/workflow-workspace.test.ts --reporter=dot(9 passed)npx vitest run src/__tests__/workflow-records.test.ts src/__tests__/workflow-docs-examples.test.ts --reporter=dot(48 passed)npm run test:e2e -- src/__tests__/e2e/workflow-workspaces.test.ts(real CLI; 1 passed)originread_only_dirtymerge_conflictnpm run test:e2e -- src/__tests__/e2e/workflow-command.test.ts src/__tests__/e2e/workflow-inputs.test.ts src/__tests__/e2e/workflow-inline.test.ts src/__tests__/e2e/workflow-subworkflow.test.ts src/__tests__/e2e/workflow-loop-fan-out.test.ts src/__tests__/e2e/workflow-signals.test.ts(10 passed)