gnhf 0.1.19 → 0.1.20
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/dist/cli.mjs +66 -32
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import process$1 from "node:process";
|
|
|
6
6
|
import { createInterface } from "node:readline";
|
|
7
7
|
import { Command, InvalidArgumentError } from "commander";
|
|
8
8
|
import yaml from "js-yaml";
|
|
9
|
-
import { execFileSync,
|
|
9
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
10
10
|
import { createServer } from "node:net";
|
|
11
11
|
import { EventEmitter } from "node:events";
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
@@ -302,32 +302,24 @@ const NOT_GIT_REPOSITORY_MESSAGE = "This command must be run inside a Git reposi
|
|
|
302
302
|
function translateGitError(error) {
|
|
303
303
|
return error instanceof Error ? error : new Error(String(error));
|
|
304
304
|
}
|
|
305
|
-
function git(args, cwd) {
|
|
305
|
+
function git(args, cwd, options = {}) {
|
|
306
306
|
try {
|
|
307
|
-
return
|
|
307
|
+
return execFileSync("git", args, {
|
|
308
308
|
cwd,
|
|
309
309
|
encoding: "utf-8",
|
|
310
|
-
stdio: "pipe"
|
|
310
|
+
stdio: "pipe",
|
|
311
|
+
...options.env ? { env: options.env } : {}
|
|
311
312
|
}).trim();
|
|
312
313
|
} catch (error) {
|
|
313
314
|
throw translateGitError(error);
|
|
314
315
|
}
|
|
315
316
|
}
|
|
316
|
-
/** Wrap a value in single quotes, escaping embedded single quotes for POSIX shells. */
|
|
317
|
-
function shellEscape(value) {
|
|
318
|
-
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
319
|
-
}
|
|
320
317
|
function isGitRepository(cwd) {
|
|
321
318
|
try {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
env: {
|
|
327
|
-
...process.env,
|
|
328
|
-
LC_ALL: "C"
|
|
329
|
-
}
|
|
330
|
-
});
|
|
319
|
+
git(["rev-parse", "--git-dir"], cwd, { env: {
|
|
320
|
+
...process.env,
|
|
321
|
+
LC_ALL: "C"
|
|
322
|
+
} });
|
|
331
323
|
return true;
|
|
332
324
|
} catch {
|
|
333
325
|
return false;
|
|
@@ -339,23 +331,41 @@ function ensureGitRepository(cwd) {
|
|
|
339
331
|
function getCurrentBranch(cwd) {
|
|
340
332
|
ensureGitRepository(cwd);
|
|
341
333
|
try {
|
|
342
|
-
return git(
|
|
334
|
+
return git([
|
|
335
|
+
"symbolic-ref",
|
|
336
|
+
"--short",
|
|
337
|
+
"HEAD"
|
|
338
|
+
], cwd);
|
|
343
339
|
} catch {
|
|
344
|
-
return git(
|
|
340
|
+
return git([
|
|
341
|
+
"rev-parse",
|
|
342
|
+
"--abbrev-ref",
|
|
343
|
+
"HEAD"
|
|
344
|
+
], cwd);
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
347
|
function ensureCleanWorkingTree(cwd) {
|
|
348
|
-
if (git("status --porcelain", cwd)) throw new Error("Working tree is not clean. Commit or stash changes first.");
|
|
348
|
+
if (git(["status", "--porcelain"], cwd)) throw new Error("Working tree is not clean. Commit or stash changes first.");
|
|
349
349
|
}
|
|
350
350
|
function createBranch(branchName, cwd) {
|
|
351
|
-
git(
|
|
351
|
+
git([
|
|
352
|
+
"checkout",
|
|
353
|
+
"-b",
|
|
354
|
+
branchName
|
|
355
|
+
], cwd);
|
|
352
356
|
}
|
|
353
357
|
function getHeadCommit(cwd) {
|
|
354
|
-
return git("rev-parse HEAD", cwd);
|
|
358
|
+
return git(["rev-parse", "HEAD"], cwd);
|
|
355
359
|
}
|
|
356
360
|
function findLegacyRunBaseCommit(runId, cwd) {
|
|
357
361
|
try {
|
|
358
|
-
const marker = git(
|
|
362
|
+
const marker = git([
|
|
363
|
+
"log",
|
|
364
|
+
"--first-parent",
|
|
365
|
+
"--reverse",
|
|
366
|
+
"--format=%H%x09%s",
|
|
367
|
+
"HEAD"
|
|
368
|
+
], cwd).split("\n").map((line) => {
|
|
359
369
|
const [sha, ...subjectParts] = line.split(" ");
|
|
360
370
|
return {
|
|
361
371
|
sha,
|
|
@@ -363,33 +373,57 @@ function findLegacyRunBaseCommit(runId, cwd) {
|
|
|
363
373
|
};
|
|
364
374
|
}).find(({ subject }) => subject === `gnhf: initialize run ${runId}` || subject === `gnhf: overwrite run ${runId}`);
|
|
365
375
|
if (!marker?.sha) return null;
|
|
366
|
-
return git(
|
|
376
|
+
return git(["rev-parse", `${marker.sha}^`], cwd);
|
|
367
377
|
} catch {
|
|
368
378
|
return null;
|
|
369
379
|
}
|
|
370
380
|
}
|
|
371
381
|
function getBranchCommitCount(baseCommit, cwd) {
|
|
372
382
|
if (!baseCommit) return 0;
|
|
373
|
-
return Number.parseInt(git(
|
|
383
|
+
return Number.parseInt(git([
|
|
384
|
+
"rev-list",
|
|
385
|
+
"--count",
|
|
386
|
+
"--first-parent",
|
|
387
|
+
`${baseCommit}..HEAD`
|
|
388
|
+
], cwd), 10);
|
|
374
389
|
}
|
|
375
390
|
function commitAll(message, cwd) {
|
|
376
|
-
git("add -A", cwd);
|
|
391
|
+
git(["add", "-A"], cwd);
|
|
377
392
|
try {
|
|
378
|
-
git(
|
|
393
|
+
git([
|
|
394
|
+
"commit",
|
|
395
|
+
"-m",
|
|
396
|
+
message
|
|
397
|
+
], cwd);
|
|
379
398
|
} catch {}
|
|
380
399
|
}
|
|
381
400
|
function resetHard(cwd) {
|
|
382
|
-
git(
|
|
383
|
-
|
|
401
|
+
git([
|
|
402
|
+
"reset",
|
|
403
|
+
"--hard",
|
|
404
|
+
"HEAD"
|
|
405
|
+
], cwd);
|
|
406
|
+
git(["clean", "-fd"], cwd);
|
|
384
407
|
}
|
|
385
408
|
function getRepoRootDir(cwd) {
|
|
386
|
-
return git("rev-parse --show-toplevel", cwd);
|
|
409
|
+
return git(["rev-parse", "--show-toplevel"], cwd);
|
|
387
410
|
}
|
|
388
411
|
function createWorktree(baseCwd, worktreePath, branchName) {
|
|
389
|
-
git(
|
|
412
|
+
git([
|
|
413
|
+
"worktree",
|
|
414
|
+
"add",
|
|
415
|
+
"-b",
|
|
416
|
+
branchName,
|
|
417
|
+
worktreePath
|
|
418
|
+
], baseCwd);
|
|
390
419
|
}
|
|
391
420
|
function removeWorktree(baseCwd, worktreePath) {
|
|
392
|
-
git(
|
|
421
|
+
git([
|
|
422
|
+
"worktree",
|
|
423
|
+
"remove",
|
|
424
|
+
"--force",
|
|
425
|
+
worktreePath
|
|
426
|
+
], baseCwd);
|
|
393
427
|
}
|
|
394
428
|
//#endregion
|
|
395
429
|
//#region src/core/agents/types.ts
|