Skip to content

feat(adopt): non-interactive --include ancestors for remote adoption - #756

Open
simsinght wants to merge 2 commits into
masterfrom
adopt-remote-include-ancestors
Open

simsinght wants to merge 2 commits into
masterfrom
adopt-remote-include-ancestors

Conversation

@simsinght

@simsinght simsinght commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

pls 🙏 my Claude needs non-interactive adoption of entire stacks

What

av adopt --remote <branch> always drops into the interactive picker, which is a wall for scripts and agents trying to mirror a coworker's stack locally. This adds an --include ancestors flag that skips the picker:

av adopt --remote feat-c --include ancestors            # adopt feat-c + its ancestors, no prompt
av adopt --remote feat-c --include ancestors --dry-run  # print the adoption plan only

It adopts the named branch and its ancestor chain up to the trunk without prompting. Bare --remote still opens the picker, so this is non-breaking. --include is a validated string flag (only ancestors today) so it can grow to descendants/stack later without adding new flags.

Tests

Extends the e2e harness, which had no coverage of the remote-adopt path:

  • the mock GitHub server now answers the pullRequest(number:) query used to walk parent PRs
  • mock-pull accepts base=<ref> and body=<file> so a remote stack with av stack metadata can be modeled

New testscript covers the --dry-run plan and --include validation.

Stacked on #755.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • av adopt --remote now supports --include=ancestors for non-interactive adoption of a remote branch and its ancestor branches.
    • Adoption can now show a dry-run plan before making changes.
    • Adopted branches now keep upstream tracking set automatically where possible.
  • Documentation

    • Updated command help and manual pages to describe the new remote adoption workflow and --include option.
  • Bug Fixes

    • Improved remote adoption behavior so branch selection and adoption plans work more reliably in automated flows.

@simsinght
simsinght requested a review from a team as a code owner June 2, 2026 20:28
@aviator-app

aviator-app Bot commented Jun 2, 2026 •

Copy link
Copy Markdown
Contributor

🔃 FlexReview Status

Common Owner: aviator-co/engineering (expert-load-balance assignment)
Owner and Assignment:

  • 🔒 aviator-co/engineering (expert-load-balance assignment)
    Owned Files
    • 🔒 docs/av-adopt.1.md
    • 🔒 e2e_tests/mock_ghgql_server.go
    • 🔒 e2e_tests/testscript_test.go
    • 🔒 cmd/av/adopt.go
    • 🔒 e2e_tests/testdata/script/adopt_remote_include_ancestors.txtar

Review SLO: 7 business hours if PR size is <= 200 LOC for the first response.
❕ This PR modifies 255 lines, which is larger than the Review SLO threshold.

@aviator-app
aviator-app Bot requested a review from jainankit June 2, 2026 20:28

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a new --include ancestors flag to the av adopt command, enabling non-interactive adoption of a remote branch and its ancestors. It includes updates to the command-line documentation, enhances the mock GitHub GraphQL server in end-to-end tests to support querying pull requests by number, and adds corresponding test coverage. The feedback suggests registering a shell completion function for the new --include flag to improve the CLI user experience.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread cmd/av/adopt.go
Comment on lines +488 to +491
adoptCmd.Flags().StringVar(
&adoptFlags.Include, "include", "",
"with --remote, non-interactively adopt the named branch and related branches\n(ancestors)",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To improve the CLI user experience, we can register a shell completion function for the new --include flag. Since the only valid value currently is ancestors (defined in adoptIncludeValues), we can provide this directly to Cobra's shell completion mechanism.

	adoptCmd.Flags().StringVar(
		&adoptFlags.Include, "include", "",
		"with --remote, non-interactively adopt the named branch and related branches\n(ancestors)",
	)
	_ = adoptCmd.RegisterFlagCompletionFunc(
		"include",
		func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
			return adoptIncludeValues, cobra.ShellCompDirectiveNoFileComp
		},
	)

Base automatically changed from adopt-remote-set-upstream-tracking to master June 2, 2026 21:17
@jainankit
jainankit requested review from tulioz and removed request for jainankit June 2, 2026 22:51
av adopt --remote opens an interactive picker, which is awkward for
scripts and agents mirroring a coworker's stack. Add --include ancestors
to skip the picker and adopt the named branch plus its ancestors up to
the trunk in one shot. --dry-run prints the adoption plan.

Also extend the e2e harness: the mock GitHub server now answers the
pullRequest(number:) query used to walk parent PRs, and mock-pull accepts
base=<ref> and body=<file> so a remote stack with av metadata can be
modeled in tests.
@simsinght
simsinght force-pushed the adopt-remote-include-ancestors branch from f364378 to 0efd2fc Compare June 3, 2026 18:51
@aviator-app

aviator-app Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Current Aviator status

Aviator will automatically update this comment as the status of the PR changes.
Comment /aviator refresh to force Aviator to re-examine your PR (or learn about other /aviator commands).

This pull request is currently open (not queued).

How to merge

To merge this PR, comment /aviator merge or add the mergequeue label.


See the real-time status of this PR on the Aviator webapp.
Use the Aviator Chrome Extension to see the status of your PR within GitHub.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8283fe06-ff47-46d0-8a6a-5441c353f684

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
e2e_tests/mock_ghgql_server.go (1)

141-158: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Unchecked type assertion can panic the mock server.

req.Variables["number"].(float64) panics if the variable is missing or of an unexpected type, crashing the mock HTTP handler goroutine with an unclear stack trace instead of a controlled test failure.

🛡️ Proposed fix using comma-ok assertion
 func (s *mockGitHubServer) handlePRByNumberQuery(req graphqlRequest) graphqlResponse {
 	// JSON numbers decode to float64.
-	number := int(req.Variables["number"].(float64))
+	numberFloat, ok := req.Variables["number"].(float64)
+	if !ok {
+		s.t.Fatalf("handlePRByNumberQuery: missing or invalid 'number' variable: %v", req.Variables["number"])
+	}
+	number := int(numberFloat)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e_tests/mock_ghgql_server.go` around lines 141 - 158, The
handlePRByNumberQuery helper in mockGitHubServer should not use an unchecked
type assertion on req.Variables["number"]; it can panic if the variable is
missing or not numeric. Update the number extraction to use a comma-ok style
check, and if the variable is absent or the wrong type, return a controlled
graphqlResponse (or fail the mock request explicitly) instead of crashing the
handler. Keep the fix scoped to handlePRByNumberQuery and the
req.Variables["number"] lookup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/av/adopt.go`:
- Around line 336-349: The dry-run preview in adopt.go is using
prInfo.Parent.Name directly, so it can report a stale parent instead of the same
open ancestor/trunk chosen by the real adoption flow. Update the dry-run block
in the adoption command to reuse the same parent-resolution logic as
initAdoption/adopt (the reparent walk) when building the “Would adopt” lines, so
the displayed parent matches what actual adoption would use.

---

Nitpick comments:
In `@e2e_tests/mock_ghgql_server.go`:
- Around line 141-158: The handlePRByNumberQuery helper in mockGitHubServer
should not use an unchecked type assertion on req.Variables["number"]; it can
panic if the variable is missing or not numeric. Update the number extraction to
use a comma-ok style check, and if the variable is absent or the wrong type,
return a controlled graphqlResponse (or fail the mock request explicitly)
instead of crashing the handler. Keep the fix scoped to handlePRByNumberQuery
and the req.Variables["number"] lookup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6183aa94-6e30-4d9c-a833-0b28366cd89c

📥 Commits

Reviewing files that changed from the base of the PR and between 65186a9 and 0efd2fc.

📒 Files selected for processing (5)
  • cmd/av/adopt.go
  • docs/av-adopt.1.md
  • e2e_tests/mock_ghgql_server.go
  • e2e_tests/testdata/script/adopt_remote_include_ancestors.txtar
  • e2e_tests/testscript_test.go

Comment thread cmd/av/adopt.go
Comment on lines +336 to +349
if adoptFlags.DryRun {
parents := make(map[string]string, len(prs))
for _, prInfo := range prs {
parents[prInfo.Name] = prInfo.Parent.Name
}
lines := []string{"Would adopt:"}
for _, target := range adoptionTargets {
lines = append(lines, fmt.Sprintf(" %s (parent: %s)", target.Short(), parents[target.Short()]))
}
return tea.Batch(
vm.AddView(uiutils.SimpleMessageView{Message: colors.SuccessStyle.Render(strings.Join(lines, "\n"))}),
tea.Quit,
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP -C3 'PullRequestState(Merged|Closed)|Parent\.Trunk|prMap\[' cmd/av/adopt.go

Repository: aviator-co/av

Length of output: 665


🏁 Script executed:

#!/bin/bash
sed -n '330,450p' cmd/av/adopt.go

Repository: aviator-co/av

Length of output: 3934


🏁 Script executed:

#!/bin/bash
sed -n '250,340p' cmd/av/adopt.go

Repository: aviator-co/av

Length of output: 2620


🏁 Script executed:

#!/bin/bash
rg -n "type RemotePRInfo|NewGetRemoteStackedPRModel|GetRemoteStackedPRModel|type AdoptingBranch|type BranchState" -S .

Repository: aviator-co/av

Length of output: 982


🏁 Script executed:

#!/bin/bash
sed -n '1,220p' internal/actions/get_remote_stacked_pr.go && printf '\n---\n' && sed -n '1,120p' internal/actions/adopt_branches.go && printf '\n---\n' && sed -n '1,120p' internal/meta/branchstate.go

Repository: aviator-co/av

Length of output: 9163


Dry-run should use the same reparent walk as adoption. prInfo.Parent.Name can still point to a merged/closed PR, so Would adopt may show a parent that differs from the branch actually adopted after initAdoption walks up to an open ancestor or trunk.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/av/adopt.go` around lines 336 - 349, The dry-run preview in adopt.go is
using prInfo.Parent.Name directly, so it can report a stale parent instead of
the same open ancestor/trunk chosen by the real adoption flow. Update the
dry-run block in the adoption command to reuse the same parent-resolution logic
as initAdoption/adopt (the reparent walk) when building the “Would adopt” lines,
so the displayed parent matches what actual adoption would use.

This branch has not been deployed

No deployments
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