gnhf 0.1.37 → 0.1.39
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/dist/cli.mjs +33 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -159,6 +159,7 @@ Pass `--current-branch` to run on the branch you are already on instead of creat
|
|
|
159
159
|
Pass `--push` to push the current branch after each successful iteration.
|
|
160
160
|
Together, `--current-branch --push` is useful for loose projects where you want a deployed or locally watched branch to update throughout the run.
|
|
161
161
|
|
|
162
|
+
- Re-running the same prompt with `--current-branch` resumes the existing `.gnhf/runs/<runId>/` history on a clean working tree and continues iteration numbering.
|
|
162
163
|
- Push failures abort the run after preserving the successful local commit.
|
|
163
164
|
- gnhf never force-pushes or auto-pulls for this mode.
|
|
164
165
|
- `--push` also works with the default `gnhf/` branch mode and sets `origin` as the upstream when needed.
|
|
@@ -276,7 +277,7 @@ You can also pass a raw custom ACP server command directly as a quoted `acp:` sp
|
|
|
276
277
|
|
|
277
278
|
- Omit it to keep the default `gnhf <iteration>: <summary>` format.
|
|
278
279
|
- Set `preset: conventional` to ask the agent for `type` and optional `scope`, then commit as `type(scope): summary` for semantic-release style workflows. Valid types are `build`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `test`, and `chore`; invalid or missing types fall back to `chore`, and empty scopes are omitted.
|
|
279
|
-
- The resolved commit-message convention is saved per run, so resuming
|
|
280
|
+
- The resolved commit-message convention is saved per run, so resuming keeps the original subject format even if `config.yml` changes later.
|
|
280
281
|
|
|
281
282
|
### Custom Agent Paths
|
|
282
283
|
|
package/dist/cli.mjs
CHANGED
|
@@ -17702,6 +17702,18 @@ function meteorCountForFrequency(frequency) {
|
|
|
17702
17702
|
function meteorsStartingBefore(meteors, rowOffset, maxStartRow) {
|
|
17703
17703
|
return meteors.filter((meteor) => rowOffset + meteor.y < maxStartRow);
|
|
17704
17704
|
}
|
|
17705
|
+
function generateSideMeteorShower(terminalWidth, sideWidth, height, count, seed) {
|
|
17706
|
+
if (sideWidth <= 0 || height <= 0 || count <= 0) return [];
|
|
17707
|
+
const leftCount = Math.max(1, Math.ceil(count / 2));
|
|
17708
|
+
const rightCount = count - leftCount;
|
|
17709
|
+
const leftMeteors = generateMeteorShower(sideWidth, height, leftCount, seed);
|
|
17710
|
+
const rightXOffset = terminalWidth - sideWidth;
|
|
17711
|
+
const rightMeteors = generateMeteorShower(sideWidth, height, rightCount, seed + 1).map((meteor) => ({
|
|
17712
|
+
...meteor,
|
|
17713
|
+
x: meteor.x + rightXOffset
|
|
17714
|
+
}));
|
|
17715
|
+
return [...leftMeteors, ...rightMeteors];
|
|
17716
|
+
}
|
|
17705
17717
|
function placeStarsInCells(cells, stars, row, xMin, xMax, xOffset, now) {
|
|
17706
17718
|
for (const star of stars) {
|
|
17707
17719
|
if (star.y !== row || star.x < xMin || star.x >= xMax) continue;
|
|
@@ -17900,6 +17912,7 @@ var Renderer = class {
|
|
|
17900
17912
|
sideStars = [];
|
|
17901
17913
|
topMeteors = [];
|
|
17902
17914
|
bottomMeteors = [];
|
|
17915
|
+
sideMeteors = [];
|
|
17903
17916
|
cachedWidth = 0;
|
|
17904
17917
|
cachedHeight = 0;
|
|
17905
17918
|
meteorFrequency;
|
|
@@ -17995,6 +18008,7 @@ var Renderer = class {
|
|
|
17995
18008
|
this.topStars = generateStarField(w, h, STAR_DENSITY, this.seedTop).map((s) => shrinkBig(s, s.y >= topHeight - proximityRows));
|
|
17996
18009
|
this.bottomStars = generateStarField(w, h, STAR_DENSITY, this.seedBottom).map((s) => shrinkBig(s, s.y < proximityRows));
|
|
17997
18010
|
this.sideStars = generateStarField(w, Math.max(BASE_CONTENT_ROWS, availableHeight), STAR_DENSITY, this.seedSide);
|
|
18011
|
+
this.sideMeteors = generateSideMeteorShower(w, Math.max(0, Math.floor((w - CONTENT_WIDTH) / 2)), Math.min(BASE_CONTENT_ROWS, availableHeight), meteorCountForFrequency(this.meteorFrequency), this.seedSide + METEOR_SEED_OFFSET);
|
|
17998
18012
|
this.topMeteors = generateMeteorShower(w, topHeight, topHeight > 0 ? meteorCountForFrequency(this.meteorFrequency) : 0, this.seedTop + METEOR_SEED_OFFSET);
|
|
17999
18013
|
this.bottomMeteors = generateMeteorShower(w, bottomHeight, bottomHeight > 0 ? meteorCountForFrequency(this.meteorFrequency) : 0, this.seedBottom + METEOR_SEED_OFFSET);
|
|
18000
18014
|
return true;
|
|
@@ -18007,7 +18021,7 @@ var Renderer = class {
|
|
|
18007
18021
|
const h = process$1.stdout.rows || 24;
|
|
18008
18022
|
const resized = this.ensureStarFields(w, h);
|
|
18009
18023
|
this.updateTerminalTitle(now);
|
|
18010
|
-
const nextCells = buildFrameCells(this.prompt, this.agentName, this.state, this.topStars, this.bottomStars, this.sideStars, now, w, h, this.topMeteors, this.bottomMeteors);
|
|
18024
|
+
const nextCells = buildFrameCells(this.prompt, this.agentName, this.state, this.topStars, this.bottomStars, this.sideStars, now, w, h, this.topMeteors, this.bottomMeteors, this.sideMeteors);
|
|
18011
18025
|
if (this.isFirstFrame || resized) {
|
|
18012
18026
|
process$1.stdout.write("\x1B[H" + nextCells.map(rowToString).join("\n"));
|
|
18013
18027
|
this.isFirstFrame = false;
|
|
@@ -18138,10 +18152,19 @@ function initializeNewBranch(prompt, cwd, schemaOptions) {
|
|
|
18138
18152
|
const runId = createBranchWithSuffix(slugifyPrompt(prompt), cwd).split("/")[1];
|
|
18139
18153
|
return setupRun(runId, prompt, baseCommit, cwd, schemaOptions);
|
|
18140
18154
|
}
|
|
18155
|
+
function promptRunId(prompt) {
|
|
18156
|
+
return slugifyPrompt(prompt).split("/")[1];
|
|
18157
|
+
}
|
|
18158
|
+
function resumeCurrentBranchRun(prompt, cwd, schemaOptions) {
|
|
18159
|
+
const runId = promptRunId(prompt);
|
|
18160
|
+
if (!existsSync(join(cwd, ".gnhf", "runs", runId))) return null;
|
|
18161
|
+
ensureCleanWorkingTree(cwd);
|
|
18162
|
+
return resumeRun(runId, cwd, schemaOptions);
|
|
18163
|
+
}
|
|
18141
18164
|
function initializeCurrentBranchRun(prompt, cwd, schemaOptions) {
|
|
18142
18165
|
ensureCleanWorkingTree(cwd);
|
|
18143
18166
|
const baseCommit = getHeadCommit(cwd);
|
|
18144
|
-
return setupRun(createRunIdWithSuffix(
|
|
18167
|
+
return setupRun(createRunIdWithSuffix(promptRunId(prompt), cwd), prompt, baseCommit, cwd, schemaOptions);
|
|
18145
18168
|
}
|
|
18146
18169
|
function branchNameWithSuffix(branchName, suffix) {
|
|
18147
18170
|
return suffix === 0 ? branchName : `${branchName}-${suffix}`;
|
|
@@ -18443,7 +18466,14 @@ program.name("gnhf").description("Before I go to bed, I tell my agents: good nig
|
|
|
18443
18466
|
program.help();
|
|
18444
18467
|
return;
|
|
18445
18468
|
}
|
|
18446
|
-
|
|
18469
|
+
const existing = resumeCurrentBranchRun(prompt, cwd, buildResumeSchemaOptions(options.stopWhen, effectiveCommitMessage));
|
|
18470
|
+
if (existing) {
|
|
18471
|
+
runInfo = existing;
|
|
18472
|
+
effectiveStopWhen = existing.stopWhen;
|
|
18473
|
+
effectiveCommitMessage = existing.commitMessage;
|
|
18474
|
+
schemaOptions = buildSchemaOptions(effectiveStopWhen, effectiveCommitMessage);
|
|
18475
|
+
startIteration = getLastIterationNumber(existing);
|
|
18476
|
+
} else runInfo = initializeCurrentBranchRun(prompt, cwd, schemaOptions);
|
|
18447
18477
|
} else if (onGnhfBranch) {
|
|
18448
18478
|
const existingRunId = currentBranch.slice(5);
|
|
18449
18479
|
const existingMetadata = peekRunMetadata(existingRunId, cwd);
|