You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(GitClone): select an existing local checkout instead of cloning (#193)
<GitClone> now has a repository-source picker: clone from a remote (unchanged)
or point at a checkout the user already has on disk. Users often have the repo
already — a long-lived infrastructure-live checkout, a work in progress branch,
a monorepo they don't want to re-download.
Picking a directory inspects it without touching it: resolve the work tree root
via `git rev-parse --show-toplevel` (so any subdirectory of the checkout works),
read the origin remote and current branch, count tracked files. That runs as the
user types or browses, so a wrong directory says so immediately. Confirming with
"Use This Repo" registers the checkout as a session worktree and emits the same
outputs a clone does, so nothing downstream can tell the two apart: same
clone_path/repo_owner/repo_name, same $REPO_FILES, same workspace file tree,
same <GitPullRequest> flow (opening against the checkout's own remote and
current branch).
Backend:
- src/domain/git/local-repo.ts: inspectLocalRepo() — root resolution, remote/ref
metadata, tracked-file count, and typed user-facing failures for a missing
directory, a file, or a directory that isn't a git work tree. A repo with no
commits is still selectable.
- GitClient.getRepoRoot() added to the service, the CLI layer, and the test stub.
- git:local-repo IPC handler. The live preview passes register:false; only the
user confirming registers the worktree and resolves GitHub numeric IDs. That
split keeps a half-typed path from granting anything.
- workspace.ts: resolveValidatedWorktree() now accepts already-registered
worktrees. Without this, workspace:register / workspace:set-active silently
rejected any checkout outside the session working directory — which is where
local checkouts normally live — so the active-worktree selection didn't stick
and REPO_FILES could point at the wrong repo. It does not widen the grant:
an unregistered path outside the session still fails.
Frontend: SourceSelect (styled after GitAuth's ProviderSelect), LocalRepoForm
with a native folder picker, and source-aware copy in the result panel. New
props: source ('clone' | 'local'), hideSourceSelect, prefilledRepoDir — the last
one starts the block on the local source. Selecting a checkout requires no
credentials; only cloning still waits on a linked auth block. Instruction mode
renders `cd <path>` instead of a git clone command.
The runbook test framework adopts a checkout for source="local" rather than
cloning, counting tracked files instead of walking .git.
Tests: 11 domain tests for inspectLocalRepo, 12 component tests driving the real
hook against a mocked IPC boundary, 2 instruction-mode tests, and 2 CLI executor
tests against a real `git init` fixture. Docs cover the new source, props, and
output behaviour.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `<GitClone>` block provides a streamlined way to clone git repositories. It works with any git upstream, and includes optional GitHub integration for browsing organizations, repositories, and branches when a GitHub token is available.
7
+
The `<GitClone>` block provides a streamlined way to bring a git repository into a runbook: clone it fresh, or point at a checkout the user already has on disk. It works with any git upstream, and includes optional GitHub integration for browsing organizations, repositories, and branches when a GitHub token is available.
8
8
9
9
Compared to using the [Command](/authoring/blocks/command/) block to clone a git repository, the GitClone block provides a purpose-built UI for cloning a git repository, the ability to search the GitHub API for orgs, repos, branches, and tags, and automatically shows the [file workspace](/authoring/workspace), where users can see the contents of the cloned repository, along with any changes to it.
10
10
@@ -39,6 +39,36 @@ When paired with a `<GitHubAuth>` block, the GitClone block enables a "Browse Gi
39
39
/>
40
40
```
41
41
42
+
### Using a Local Checkout
43
+
44
+
Users often already have the repository cloned — a long-lived `infrastructure-live` checkout, a work in progress branch, a monorepo they never want to re-download. The block's source picker lets them choose **Use local checkout** and select that directory instead of cloning.
45
+
46
+
Selecting a directory reads it only: the block resolves the repository root (so any subdirectory of the checkout works), reads the `origin` remote and current branch, and registers the repo exactly as a clone would. Nothing is fetched, pulled, or modified, and no credentials are needed — the files are already there.
47
+
48
+
```mdx
49
+
<GitClone
50
+
id="repo"
51
+
title="Select Your Infrastructure Repo"
52
+
prefilledRepoDir="~/dev/infrastructure-live"
53
+
/>
54
+
```
55
+
56
+
Setting `prefilledRepoDir` starts the block on the local source. Use `source` to choose the starting source explicitly, and `hideSourceSelect` to remove the choice altogether:
Everything downstream behaves the same either way: the same `clone_path`, `repo_owner`, and `repo_name` outputs, the same `$REPO_FILES` variable, the same workspace file tree, and the same [`<GitPullRequest>`](/authoring/blocks/gitpullrequest) integration — a pull request opens against the checkout's `origin` remote and current branch.
67
+
68
+
<Asidetype="caution">
69
+
A checkout with no `origin` remote can still be selected, but blocks that open a pull request need one. The block says so inline when it finds no remote.
70
+
</Aside>
71
+
42
72
### Pre-filled Values
43
73
44
74
You can pre-populate the URL, ref, sparse checkout path, and local path fields. Users can still edit these values before cloning. This follows the same pattern as the `prefilledVariables` prop on the [Inputs](/authoring/blocks/inputs) block.
@@ -68,6 +98,9 @@ You can pre-populate the URL, ref, sparse checkout path, and local path fields.
68
98
|`prefilledLocalPath`|`string`| No | Pre-fills the local path (relative to the current working directory) where files will be cloned. Defaults to the repository name if empty. |
69
99
|`usePty`|`boolean`| No | Whether to use a pseudo-terminal (PTY) for the git clone process. Defaults to `true`. PTY enables rich output like progress bars and colors. Set to `false` if your environment doesn't support PTY. |
70
100
|`showFileTree`|`boolean`| No | Whether to show the cloned repository's file tree in the workspace panel after cloning. Defaults to `true`. When enabled, the "All files" and "Changed" tabs display the cloned files and any subsequent modifications. |
101
+
|`source`|`'clone' \| 'local'`| No | Which source the block starts on: clone a remote repo, or use an existing local checkout. Defaults to `local` when `prefilledRepoDir` is set, otherwise `clone`. |
102
+
|`hideSourceSelect`|`boolean`| No | Hides the source picker and locks the block to `source`. Defaults to `false`. |
103
+
|`prefilledRepoDir`|`string`| No | Pre-fills the local checkout directory. Any directory inside the checkout works — the repository root is resolved from it. |
71
104
72
105
### Ref Selection
73
106
@@ -89,6 +122,8 @@ When `showFileTree` is `true` (the default), the GitClone block registers the cl
89
122
90
123
Set `showFileTree={false}` if you don't want the cloned repository to appear in the workspace panel (e.g., for helper repositories that the user doesn't need to browse).
91
124
125
+
A local checkout registers with the workspace the same way. Note that the **Changed** tab then shows any uncommitted changes the checkout already had, not just the ones the runbook makes.
126
+
92
127
### Accepted Git URL Formats
93
128
94
129
The GitClone block accepts the following URL formats:
@@ -168,6 +203,8 @@ After a successful clone, the GitClone block produces outputs that can be refere
168
203
|`repo_id`| Immutable GitHub numeric ID of the repository (when a GitHub token is available) |`87654321`|
169
204
|`repo_url`| The full URL of the cloned repository |`https://github.com/acme-corp/infrastructure-live`|
170
205
206
+
For a local checkout, `clone_path` is the repository root the user selected, and `repo_owner` / `repo_name` come from its `origin` remote (omitted when the repo has no remote).
207
+
171
208
Reference outputs in downstream blocks using template variables:
0 commit comments