Skip to content

feat(cli): add init-remote command for github repository creation#409

Open
arielshad wants to merge 11 commits into
mainfrom
feat/github-remote-init
Open

feat(cli): add init-remote command for github repository creation#409
arielshad wants to merge 11 commits into
mainfrom
feat/github-remote-init

Conversation

@arielshad
Copy link
Copy Markdown
Contributor

Summary

Add a new shep repo init-remote CLI command that creates a GitHub repository via gh repo create and configures the local git remote for repositories that don't yet have one. This bridges the gap between local-only repos and GitHub-dependent shep workflows (PRs, CI, push).

Changes across Clean Architecture layers:

  • Domain/Interface: Extended IGitPrService with createGitHubRepo() and addRemote() methods; added new GitPrErrorCode values (GH_NOT_FOUND, AUTH_FAILURE, REPO_CREATE_FAILED)
  • Infrastructure: Implemented service methods in GitPrService using gh repo create and git remote add subprocess calls with the existing ExecFunction injection pattern
  • Application: New InitRemoteRepositoryUseCase orchestrating the full flow — validate gh CLI availability, check hasRemote() guard, create repo, add remote, auto-push current branch
  • Presentation/CLI: New init-remote subcommand under repo command group with [name] positional arg, --public flag, and --org <name> option
  • DI: Registered new use case in the container
  • Specs: Full spec-driven workflow artifacts (spec, research, plan, tasks, feature YAML, evidence)

Evidence

Evidence Task
GitPrService.addRemote unit tests — 3 tests passing task-3
GitPrService.createGitHubRepo unit tests — 7 tests passing task-4
InitRemoteRepositoryUseCase unit tests — 12 tests passing task-6
CLI integration tests — 17 tests passing task-10
CLI help output confirms command registration task-9
TypeScript build — zero errors task-1
Full suite — 4087 unit + 501 integration tests passing, lint clean task-7

Test plan

  • Unit tests for addRemote() (correct args, void return, error wrapping)
  • Unit tests for createGitHubRepo() (private/public/org, URL return, ENOENT→GH_NOT_FOUND, auth→AUTH_FAILURE, generic→REPO_CREATE_FAILED)
  • Unit tests for InitRemoteRepositoryUseCase (happy path, guards, error propagation, name derivation, org support, visibility, Windows paths, actionable messages)
  • Integration tests for CLI command (registration, arg/option parsing, success output, error handling for all error codes)
  • Full test suite regression check (4087 unit + 501 integration — all green)
  • Build verification (tsc compiles with zero errors)
  • Lint verification (eslint clean)

🤖 Generated with Claude Code

arielshad and others added 10 commits March 17, 2026 18:35
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… remote init

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ervice

Extend IGitPrService interface with createGitHubRepo() and addRemote()
method signatures for GitHub remote initialization. Add
REMOTE_ALREADY_EXISTS and REPO_CREATE_FAILED to GitPrErrorCode enum.
Add stub implementations in GitPrService and update all test mocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…o git-pr service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements InitRemoteRepositoryUseCase that orchestrates the full flow:
validates gh CLI availability via IToolInstallerService, guards against
existing remotes, derives repo name from cwd basename, and delegates to
IGitPrService.createGitHubRepo() for atomic create+remote+push.

Includes comprehensive unit tests covering happy path, gh not installed,
remote already exists, error propagation, custom name, org support,
public/private visibility, and Windows path handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@arielshad arielshad force-pushed the feat/github-remote-init branch from 493a883 to 5bdd852 Compare March 17, 2026 16:36
Add createGitHubRepo and addRemote mock methods to IGitPrService mock
to satisfy the interface contract after new methods were added.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Dev Release Published

Artifact Version Install
npm 1.129.2-pr409.8d19a07 npm install -g @shepai/cli@1.129.2-pr409.8d19a07

Published from commit a33d37f | View CI

arielshad added a commit that referenced this pull request Apr 6, 2026
)

## Summary

Adds three related capabilities for working with remote GitHub
repositories, unifying the work from PRs #409, #430, and #434 into a
single feature on current main:

- **`shep repo init-remote [name]`** — creates a GitHub repository from
a local one with no remote (via `gh repo create --source=.
--remote=origin --push`)
- **`shep feat new --remote <url>`** — clones (or auto-forks) a GitHub
repo then creates a feature on it, conflicts with `--repo`
- **Web UI** — shows a "Fork" badge on forked repositories in the repo
picker; `githubImport` feature flag now defaults to `true`

## Key changes

### Domain
- `Repository` entity gains `isFork?: boolean` and `upstreamUrl?:
string` (TypeSpec + generated output)
- Migration `055-add-repository-fork-fields` adds `is_fork` and
`upstream_url` columns + `idx_repositories_upstream_url` index
(idempotent)

### Auto-fork detection
- `IGitHubRepositoryService` gains `getAuthenticatedUser()`,
`checkPushAccess()`, `forkRepository()` + `GitHubForkError`
- `ImportGitHubRepositoryUseCase` now checks push access before cloning.
When the user lacks write permission, it forks via `gh repo fork`,
clones the fork, sets `upstream` remote, and persists fork metadata
- `IRepositoryRepository.findByUpstreamUrl()` for fork deduplication

### Init remote
- `IGitPrService` gains `createGitHubRepo()`, `addRemote()` +
`REMOTE_ALREADY_EXISTS`, `REPO_CREATE_FAILED` error codes
- New `InitRemoteRepositoryUseCase` guards against existing remotes and
delegates to `gh repo create`

### Feature creation from remote
- New `CreateFeatureFromRemoteUseCase` — composite that chains import →
create feature
- Two-phase API: `execute()` for CLI, `createRecord()` +
`initializeAndSpawn()` for Web (fast optimistic UI)

### i18n
- New translation keys for `repo.initRemote.*` and
`feat.new.{remoteOption,remoteConflict,forkedInfo}` added to all 8
locales

## Test plan

- [x] `pnpm typecheck` — zero errors
- [x] `pnpm lint:fix` — clean
- [x] `pnpm test:unit` — **388 files, 5585 tests passing** (includes 44
new tests)
- [x] `pnpm test:int` — **50 files, 595 tests passing** (migration 055
runs cleanly)
- [x] `pnpm build` — clean CLI build
- [x] `pnpm build:storybook` — clean storybook build with new
`WithForkBadges` story
- [ ] Manual: `shep repo init-remote my-test-repo` on a fresh local repo
- [ ] Manual: `shep feat new --remote
https://github.com/someone/public-repo "test feature"` (triggers
auto-fork path)
- [ ] Manual: Web UI — import a repo you don't have push access to,
verify "Fork" badge appears

## Notes

- Complementary to existing `IGitForkService` (PR #525, merged) which
handles fork-and-PR **within** worktrees. The new fork methods on
`IGitHubRepositoryService` handle auto-fork at **import time** — these
are different code paths and do not conflict.
- Migration 055 uses the umzug `MigrationParams` signature with
idempotent column/index checks, consistent with migration 054.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
blackpc pushed a commit that referenced this pull request Apr 6, 2026
# [1.175.0](v1.174.0...v1.175.0) (2026-04-06)

### Features

* **domain:** add unified remote repository support with auto-fork ([#531](#531)) ([64b8dfe](64b8dfe)), closes [#409](#409) [#430](#430) [#434](#434) [#525](#525)
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