mergie-cli 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/package.json +1 -1
- package/src/daemon/createRegistry.ts +5 -3
- package/src/services/git.ts +21 -7
package/README.md
CHANGED
|
@@ -30,7 +30,8 @@ review (just the new commits since last time) awkward, and can't help you naviga
|
|
|
30
30
|
|
|
31
31
|
- **[Bun](https://bun.sh)** ≥ 1.2 (mergie's runtime).
|
|
32
32
|
- **git** and the **[GitHub CLI](https://cli.github.com) (`gh`)**, authenticated
|
|
33
|
-
(`gh auth login`). mergie reuses `gh`'s token for
|
|
33
|
+
(`gh auth login`). mergie reuses `gh`'s token for **both** API access and cloning — it clones over
|
|
34
|
+
HTTPS via gh's credential helper, so **no SSH key or host-key setup is needed**.
|
|
34
35
|
- *(Optional, for AI features)* Claude access for the Claude Agent SDK — e.g. an
|
|
35
36
|
`ANTHROPIC_API_KEY` in your environment.
|
|
36
37
|
|
package/package.json
CHANGED
|
@@ -174,13 +174,15 @@ function makeWorkspace(input: WorkspaceInputs): Workspace {
|
|
|
174
174
|
const artifacts = artifactsRepo(db);
|
|
175
175
|
const aiReviews = aiReviewsRepo(db);
|
|
176
176
|
const aiReviewTracker = createAiReviewTracker();
|
|
177
|
-
|
|
177
|
+
// Clone over HTTPS on the PR's own host (honours GitHub Enterprise), authed by
|
|
178
|
+
// the gh credential helper — reuses the user's gh login, no SSH setup needed.
|
|
179
|
+
const remoteUrl = `https://${ref.host}/${ref.owner}/${ref.repo}.git`;
|
|
178
180
|
let cloned = false;
|
|
179
181
|
let baselineSha = "";
|
|
180
182
|
|
|
181
183
|
async function ensureClone(): Promise<void> {
|
|
182
184
|
if (cloned) return;
|
|
183
|
-
await git.cloneOrFetch(
|
|
185
|
+
await git.cloneOrFetch(remoteUrl, [`refs/pull/${ref.number}/head`, meta.baseRef]);
|
|
184
186
|
baselineSha = (await git.mergeBase(`origin/${meta.baseRef}`, meta.headSha)) || meta.baseRef;
|
|
185
187
|
cloned = true;
|
|
186
188
|
}
|
|
@@ -320,7 +322,7 @@ function makeWorkspace(input: WorkspaceInputs): Workspace {
|
|
|
320
322
|
pr.body = fresh.body;
|
|
321
323
|
pr.baseRef = fresh.baseRef;
|
|
322
324
|
pr.headRef = fresh.headRef;
|
|
323
|
-
await git.cloneOrFetch(
|
|
325
|
+
await git.cloneOrFetch(remoteUrl, [`refs/pull/${ref.number}/head`, fresh.baseRef]);
|
|
324
326
|
baselineSha = (await git.mergeBase(`origin/${fresh.baseRef}`, fresh.headSha)) || fresh.baseRef;
|
|
325
327
|
cloned = true;
|
|
326
328
|
},
|
package/src/services/git.ts
CHANGED
|
@@ -37,16 +37,18 @@ export interface GitService {
|
|
|
37
37
|
/**
|
|
38
38
|
* Ensure the repository is available locally and up to date.
|
|
39
39
|
*
|
|
40
|
-
* - If `<cloneDir>/.git` is absent: runs `git clone <
|
|
40
|
+
* - If `<cloneDir>/.git` is absent: runs `git clone <remoteUrl> <cloneDir>`.
|
|
41
41
|
* - If present: runs `git -C <cloneDir> fetch origin <refs...>`.
|
|
42
42
|
*
|
|
43
|
+
* Both paths authenticate HTTPS remotes through the gh CLI credential helper
|
|
44
|
+
* (see {@link GH_CREDENTIAL_ARGS}), so no SSH key or host-key trust is needed.
|
|
43
45
|
* Throws if the git process exits with a non-zero code; the error message
|
|
44
46
|
* includes stderr so callers can surface the reason.
|
|
45
47
|
*
|
|
46
|
-
* @param
|
|
47
|
-
* @param refs
|
|
48
|
+
* @param remoteUrl - HTTPS remote URL, e.g. `https://github.com/org/repo.git`.
|
|
49
|
+
* @param refs - Ref names / refspecs to fetch (e.g. `["main", "refs/pull/1/head"]`).
|
|
48
50
|
*/
|
|
49
|
-
cloneOrFetch(
|
|
51
|
+
cloneOrFetch(remoteUrl: string, refs: string[]): Promise<void>;
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* List commits in the range `startSha..endSha`, ordered oldest → newest.
|
|
@@ -164,6 +166,18 @@ function wsArgs(ignoreWhitespace: boolean | undefined): readonly string[] {
|
|
|
164
166
|
return ignoreWhitespace ? [IGNORE_WHITESPACE_ARG] : [];
|
|
165
167
|
}
|
|
166
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Per-command git config that authenticates HTTPS remotes via the **gh CLI's
|
|
171
|
+
* credential helper**, so cloning/fetching reuses the user's existing `gh`
|
|
172
|
+
* login (no separate SSH key or host-key trust required). The empty first
|
|
173
|
+
* helper resets any inherited helper; the second delegates to `gh`. Passed as
|
|
174
|
+
* `-c` flags so the user's global git config is never modified.
|
|
175
|
+
*/
|
|
176
|
+
const GH_CREDENTIAL_ARGS = [
|
|
177
|
+
"-c", "credential.helper=",
|
|
178
|
+
"-c", "credential.helper=!gh auth git-credential",
|
|
179
|
+
] as const;
|
|
180
|
+
|
|
167
181
|
// ---------------------------------------------------------------------------
|
|
168
182
|
// Internal helpers
|
|
169
183
|
// ---------------------------------------------------------------------------
|
|
@@ -194,11 +208,11 @@ export function createGitService(
|
|
|
194
208
|
runner: CommandRunner = bunRunner,
|
|
195
209
|
): GitService {
|
|
196
210
|
return {
|
|
197
|
-
async cloneOrFetch(
|
|
211
|
+
async cloneOrFetch(remoteUrl, refs) {
|
|
198
212
|
const hasGit = existsSync(`${cloneDir}/.git`);
|
|
199
213
|
const args: string[] = hasGit
|
|
200
|
-
? ["-C", cloneDir, "fetch", "origin", ...refs]
|
|
201
|
-
: ["clone",
|
|
214
|
+
? [...GH_CREDENTIAL_ARGS, "-C", cloneDir, "fetch", "origin", ...refs]
|
|
215
|
+
: [...GH_CREDENTIAL_ARGS, "clone", remoteUrl, cloneDir];
|
|
202
216
|
|
|
203
217
|
const result = await runner.run("git", args);
|
|
204
218
|
if (result.exitCode !== 0) {
|