Skip to content

Conversation

@newhook
Copy link
Owner

@newhook newhook commented Jan 29, 2026

Summary

This PR adds the ability to import existing GitHub pull requests into work units. This is useful for:

  • Taking over work from another developer
  • Reviewing external PRs locally with the co tooling
  • Continuing work on stalled PRs
  • Testing PRs in the local environment

Changes

CLI Command (cmd/work_import_pr.go)

  • New co work import-pr <pr-url> command
  • Fetches PR metadata, displays PR info, creates optional bead
  • Delegates worktree creation to control plane for async execution
  • Options:
    • --branch <name>: Override the local branch name
  • Sets up PR URL and schedules feedback polling immediately

GitHub Client Extensions (internal/github/client.go)

  • Added GetPRMetadata() method to fetch comprehensive PR metadata (title, body, branch names, author, labels, state, timestamps)

Work Package PR Import (internal/work/import_pr.go)

  • PRImporter struct that orchestrates:
    • Fetching PR metadata
    • Setting up worktree from PR branch using refs/pull/<n>/head refs
    • Bead creation with deduplication via external_ref
  • Mapper functions to convert PR metadata to bead options:
    • Infers issue type from PR labels (feature, bug, task)
    • Maps priority from labels (P0-P4)
    • Formats description with PR metadata and links

Control Plane Handler (internal/control/handler_import_pr.go)

  • New async handler for PR import operations
  • Handles worktree creation, git operations, and orchestrator spawning
  • Ensures consistent error handling and retry capabilities

Git Operations (internal/git/git.go)

  • Added FetchPRRef() method to fetch PR head refs (refs/pull/<n>/head) into local branches

TUI Integration (internal/tui/)

  • PR import panel accessible from the TUI
  • Input field for PR URL with validation
  • Preview panel showing PR details before import
  • Keyboard shortcuts for quick navigation

Architectural Refactoring

  • Delegated to Control Plane: Both co work create and co work import-pr now delegate worktree creation to the control plane, reducing code duplication and improving reliability
  • Consolidated DestroyWork: Unified destruction logic between CLI and control plane handler
  • Async Work Functions: Updated internal/work/work.go with CreateWorkAsyncWithOptions and ImportPRAsync for clean CLI integration

Tests (internal/work/import_pr_test.go)

Comprehensive unit tests covering:

  • PRImporter setup with mocked dependencies
  • SetupWorktreeFromPR success and error scenarios
  • FetchPRMetadata functionality
  • MapPRToBeadCreate mapping
  • Type, priority, and status inference from labels
  • FormatBeadDescription output
  • Priority parsing edge cases

Architecture

The PR import logic lives in internal/work/ because it's work-related business logic.
The internal/github/ package stays focused on GitHub API operations only.
Heavy operations (worktree creation, git push, mise init) are delegated to the control plane for async execution.

Files Changed

  • cmd/work.go - Refactored to delegate worktree creation to control plane
  • cmd/work_import_pr.go - New CLI command for PR import
  • internal/control/handler_import_pr.go - New control plane handler
  • internal/control/handler_destroy_worktree.go - Consolidated with work.DestroyWork()
  • internal/git/git.go - FetchPRRef method
  • internal/github/client.go - GetPRMetadata method
  • internal/tui/tui_panel_pr_import.go - TUI panel for PR import
  • internal/work/import_pr.go - PR import business logic
  • internal/work/import_pr_test.go - Comprehensive tests
  • internal/work/work.go - Async work creation functions

Issues Resolved

  • ✓ ac-ybob: Support "import" of a PR into a work (epic)
  • ✓ ac-ybob.1: Add CLI command for PR import
  • ✓ ac-ybob.2: Add PR import panel to TUI
  • ✓ ac-ybob.3: Implement PR metadata fetching
  • ✓ ac-ybob.4: Handle worktree creation from PR branch
  • ✓ ac-ybob.5: Add optional bead creation from PR
  • ✓ ac-ybob.6: Add tests for PR import functionality
  • ✓ ac-ybob.12: Refactor cmd/work.go to delegate to control plane
  • ✓ ac-ybob.13: Refactor cmd/work_import_pr.go to delegate to control plane
  • ✓ ac-ybob.14: Consolidate DestroyWork logic
  • ✓ ac-ybob.15: Update async work functions for CLI integration

Usage Examples

# Basic import
co work import-pr https://github.com/owner/repo/pull/123

# Import with custom branch name
co work import-pr https://github.com/owner/repo/pull/123 --branch my-branch

Testing

  • Unit tests pass: go test ./internal/work/...
  • Manual testing: Import real PRs from GitHub
  • CI: All checks passing

🤖 Generated with Claude Code

newhook and others added 16 commits January 29, 2026 11:40
Add GetPRMetadata method to GitHub client that fetches comprehensive PR
metadata including title, body, branch names, base branch, author, labels,
draft status, merge status, and timestamps. Supports both PR URLs and PR
numbers as input.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add FetchPRRef method to git operations that fetches PR refs using
GitHub's refs/pull/<n>/head reference. This handles both same-repo
PRs and fork PRs.

Create PRImporter helper that orchestrates:
- Fetching PR metadata
- Fetching the PR's head ref
- Creating a worktree from the PR's branch

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add mapper functions to convert PR metadata to bead creation options:
- MapPRToBeadCreate: Converts PR metadata to bead options
- FormatBeadDescription: Formats bead description with PR metadata
- mapPRType/mapPRPriority/mapPRStatus: Infer bead fields from PR

Add CreateBeadFromPR method to PRImporter that:
- Creates a bead from PR metadata
- Sets external_ref to PR URL for deduplication
- Supports skipping if bead already exists
- Allows overriding title, type, and priority

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Implements the 'co work import-pr <pr-url>' command that creates a work unit
from an existing GitHub PR. Features:
- Fetches PR metadata using the existing PRImporter
- Creates a worktree from the PR's branch
- Sets up work record with PR URL and feedback polling
- Optional bead creation from PR metadata (--create-bead)
- Auto workflow support (--auto)
- Branch name override (--branch)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Implements a new TUI panel for importing GitHub PRs, accessible via 'I' key.
Features:
- URL input field for GitHub PR URLs
- Preview functionality to fetch and display PR metadata
- Create Bead checkbox to track PR in beads system
- Auto Run checkbox to run automated workflow after import
- Similar UX to the existing Linear import panel

Also adds ViewPRImportInline mode, message handling for preview and import
completion, and proper panel syncing and rendering.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Added tests for the PR import feature including:
- PRImporter creation and setup tests
- SetupWorktreeFromPR with various scenarios (success, custom branch,
  metadata errors, fetch errors, worktree create errors)
- FetchPRMetadata delegation tests
- MapPRToBeadCreate mapping tests
- mapPRType inference tests (bug, feature, task from labels/title)
- mapPRPriority inference tests (P0-P4 from labels)
- mapPRStatus conversion tests (open, closed, merged states)
- FormatBeadDescription formatting tests
- parsePriority string-to-int conversion tests
- Data structure tests for CreateBeadOptions, CreateBeadResult,
  PRMetadata, and BeadCreateOptions

Implements ac-ybob.6

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Change os.Mkdir permissions from 0755 to 0750 (G301)
- Explicitly ignore os.RemoveAll errors with _ = prefix (G104)

These are cleanup operations during error handling where ignoring
the cleanup error is intentional to avoid masking the original error.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove CreateBead option (always create, required for work)
- Remove Auto option (doesn't make sense for PR import)
- Remove Preview button (auto-load on Enter)
- Simplify tab order: input → Import → Cancel
- Add Shift+I keybinding to help screen

Make TUI PR import async via control plane:
- Add TaskTypeImportPR task type
- Add HandleImportPRTask handler
- Add work.ImportPRAsync function
- TUI schedules task instead of blocking

CLI import unchanged (sync output is desired there).

Co-Authored-By: Claude Opus 4.5 <[email protected]>
The PR import task was scheduled but EnsureControlPlane wasn't called,
so the control plane wouldn't start to process the task.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
The tab's shell needs time to initialize before we can execute commands.
Without this delay, the command was being sent before the shell was ready,
causing the control plane to never actually start.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Instead of CreateTab + sleep + ExecuteCommand (which had race conditions),
use CreateTabWithCommand which uses a zellij layout to execute the command
directly when creating the tab.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
The internal/github/ package should only contain GitHub API operations.
The PR import orchestration logic (worktree setup, bead creation) is
business logic that belongs in the work package.

Moved to internal/work/import_pr.go:
- PRImporter struct and methods
- CreateBeadOptions, CreateBeadResult types
- Mapper functions (mapPRToBeadCreate, formatBeadDescription, etc.)
- Helper functions (findExistingPRBead, parsePriority)

Deleted from internal/github/:
- import.go
- import_test.go
- mapper.go

Updated callers in cmd/, internal/control/, and internal/tui/.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add BeadIDs field to CreateWorkAsyncOptions for immediate bead addition
- Update ImportPRAsync to add root issue bead immediately before scheduling
- Update handler_import_pr.go to check for existing beads before adding

This allows CLI commands to pass beads during async work creation rather
than having the control plane add them separately.

Closes ac-ybob.15

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Refactored handler_destroy_worktree.go to call work.DestroyWork()
instead of duplicating the destruction logic. This ensures consistency
between CLI and control plane destruction behavior.

Closes ac-ybob.14

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Simplified cmd/work_import_pr.go to use ImportPRAsync
- Removed duplicate worktree creation, git push, and mise init code
- Kept user-facing operations: PR metadata display, bead creation
- Control plane now handles the heavy lifting asynchronously

This aligns with the async work creation pattern used by other commands.

Closes ac-ybob.13

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Use CreateWorkAsyncWithOptions instead of inline worktree creation
- Remove unused imports: cosignal, mise, names, worktree
- Keep user interaction (branch prompting/validation) in the command
- Control plane now handles worktree, git push, mise init, orchestrator spawn
@newhook newhook merged commit 4b543f0 into main Jan 30, 2026
3 checks passed
@newhook newhook deleted the feat/support-import-of-a-pr-into-a-work branch January 30, 2026 03:05
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.

2 participants