gnhf 0.1.36 → 0.1.38
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 +3 -1
- package/dist/cli.mjs +116 -15
- 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.
|
|
@@ -203,6 +204,7 @@ If you run `gnhf` on an existing `gnhf/` branch with a different prompt, gnhf as
|
|
|
203
204
|
| `--worktree` | Run in a separate git worktree (enables multiple agents concurrently) | `false` |
|
|
204
205
|
| `--current-branch` | Run on the current branch instead of creating a `gnhf/` branch | `false` |
|
|
205
206
|
| `--push` | Push the current branch after each successful iteration | `false` |
|
|
207
|
+
| `--meteor-frequency <n>` | Set TUI meteor frequency from 0 to 5 (`0` disables meteors) | `3` |
|
|
206
208
|
| `--version` | Show version | |
|
|
207
209
|
|
|
208
210
|
## Configuration
|
|
@@ -275,7 +277,7 @@ You can also pass a raw custom ACP server command directly as a quoted `acp:` sp
|
|
|
275
277
|
|
|
276
278
|
- Omit it to keep the default `gnhf <iteration>: <summary>` format.
|
|
277
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.
|
|
278
|
-
- 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.
|
|
279
281
|
|
|
280
282
|
### Custom Agent Paths
|
|
281
283
|
|
package/dist/cli.mjs
CHANGED
|
@@ -17287,6 +17287,7 @@ const STAR_CHARS = [
|
|
|
17287
17287
|
"°",
|
|
17288
17288
|
"°"
|
|
17289
17289
|
];
|
|
17290
|
+
const MIN_METEOR_START_GAP_MS = 500;
|
|
17290
17291
|
function generateStarField(width, height, density, seed) {
|
|
17291
17292
|
const stars = [];
|
|
17292
17293
|
let s = seed;
|
|
@@ -17321,6 +17322,47 @@ function getStarState(star, now) {
|
|
|
17321
17322
|
if (t > .025) return "bright";
|
|
17322
17323
|
return "dim";
|
|
17323
17324
|
}
|
|
17325
|
+
function generateMeteorShower(width, height, count, seed) {
|
|
17326
|
+
if (width <= 0 || height <= 0 || count <= 0) return [];
|
|
17327
|
+
const meteors = [];
|
|
17328
|
+
let s = seed % 2147483647;
|
|
17329
|
+
if (s <= 0) s += 2147483646;
|
|
17330
|
+
const rand = () => {
|
|
17331
|
+
s = s * 16807 % 2147483647;
|
|
17332
|
+
return s / 2147483647;
|
|
17333
|
+
};
|
|
17334
|
+
for (let i = 0; i < count; i++) {
|
|
17335
|
+
const length = Math.min(height, 2 + (i + Math.floor(rand() * 6)) % 6);
|
|
17336
|
+
const xMax = Math.max(1, width - length);
|
|
17337
|
+
const yMin = Math.max(0, length - 1);
|
|
17338
|
+
const yMaxExclusive = Math.max(yMin + 1, Math.ceil(height * .75));
|
|
17339
|
+
const ySpan = Math.max(1, yMaxExclusive - yMin);
|
|
17340
|
+
const period = 16e3 + rand() * 2e4;
|
|
17341
|
+
const duration = count >= 8 ? 3e3 + rand() * 600 : 900 + rand() * 500;
|
|
17342
|
+
meteors.push({
|
|
17343
|
+
x: Math.floor(rand() * xMax),
|
|
17344
|
+
y: yMin + Math.floor(rand() * ySpan),
|
|
17345
|
+
length,
|
|
17346
|
+
phase: i === 0 ? 0 : i * (MIN_METEOR_START_GAP_MS + 80) + rand() * 60,
|
|
17347
|
+
period,
|
|
17348
|
+
duration
|
|
17349
|
+
});
|
|
17350
|
+
}
|
|
17351
|
+
return meteors;
|
|
17352
|
+
}
|
|
17353
|
+
function getMeteorTrail(meteor, now) {
|
|
17354
|
+
const cycleTime = ((now - meteor.phase) % meteor.period + meteor.period) % meteor.period;
|
|
17355
|
+
if (cycleTime >= meteor.duration) return [];
|
|
17356
|
+
const step = Math.floor(cycleTime / 120);
|
|
17357
|
+
const cells = [];
|
|
17358
|
+
for (let i = 0; i < meteor.length; i++) cells.push({
|
|
17359
|
+
x: meteor.x - step + i,
|
|
17360
|
+
y: meteor.y + step - i,
|
|
17361
|
+
state: i === 0 ? "bright" : "dim",
|
|
17362
|
+
char: "╱"
|
|
17363
|
+
});
|
|
17364
|
+
return cells;
|
|
17365
|
+
}
|
|
17324
17366
|
//#endregion
|
|
17325
17367
|
//#region src/utils/moon.ts
|
|
17326
17368
|
const MOON_PHASES = [
|
|
@@ -17544,6 +17586,8 @@ const CONTENT_WIDTH = 63;
|
|
|
17544
17586
|
const MAX_PROMPT_LINES = 3;
|
|
17545
17587
|
const BASE_CONTENT_ROWS = 24;
|
|
17546
17588
|
const STAR_DENSITY = .035;
|
|
17589
|
+
const DEFAULT_METEOR_FREQUENCY = 3;
|
|
17590
|
+
const METEOR_SEED_OFFSET = 101;
|
|
17547
17591
|
const TICK_MS = 200;
|
|
17548
17592
|
const MOONS_PER_ROW = 30;
|
|
17549
17593
|
const MOON_PHASE_PERIOD = 1600;
|
|
@@ -17647,6 +17691,17 @@ function starStyle(state) {
|
|
|
17647
17691
|
if (state === "dim") return "dim";
|
|
17648
17692
|
return "normal";
|
|
17649
17693
|
}
|
|
17694
|
+
function meteorCountForFrequency(frequency) {
|
|
17695
|
+
if (frequency <= 0) return 0;
|
|
17696
|
+
if (frequency === 1) return 1;
|
|
17697
|
+
if (frequency === 2) return 2;
|
|
17698
|
+
if (frequency === 3) return 4;
|
|
17699
|
+
if (frequency === 4) return 6;
|
|
17700
|
+
return 28;
|
|
17701
|
+
}
|
|
17702
|
+
function meteorsStartingBefore(meteors, rowOffset, maxStartRow) {
|
|
17703
|
+
return meteors.filter((meteor) => rowOffset + meteor.y < maxStartRow);
|
|
17704
|
+
}
|
|
17650
17705
|
function placeStarsInCells(cells, stars, row, xMin, xMax, xOffset, now) {
|
|
17651
17706
|
for (const star of stars) {
|
|
17652
17707
|
if (star.y !== row || star.x < xMin || star.x >= xMax) continue;
|
|
@@ -17663,15 +17718,28 @@ function placeStarsInCells(cells, stars, row, xMin, xMax, xOffset, now) {
|
|
|
17663
17718
|
};
|
|
17664
17719
|
}
|
|
17665
17720
|
}
|
|
17666
|
-
function
|
|
17721
|
+
function placeMeteorsInCells(cells, meteors, row, xMin, xMax, xOffset, now) {
|
|
17722
|
+
for (const meteor of meteors) for (const trail of getMeteorTrail(meteor, now)) {
|
|
17723
|
+
if (trail.y !== row || trail.x < xMin || trail.x >= xMax) continue;
|
|
17724
|
+
const localX = trail.x - xOffset;
|
|
17725
|
+
cells[localX] = {
|
|
17726
|
+
char: trail.char,
|
|
17727
|
+
style: trail.state === "bright" ? "bold" : "dim",
|
|
17728
|
+
width: 1
|
|
17729
|
+
};
|
|
17730
|
+
}
|
|
17731
|
+
}
|
|
17732
|
+
function renderStarLineCells(stars, meteors, width, y, now) {
|
|
17667
17733
|
const cells = emptyCells(width);
|
|
17668
17734
|
placeStarsInCells(cells, stars, y, 0, width, 0, now);
|
|
17735
|
+
placeMeteorsInCells(cells, meteors, y, 0, width, 0, now);
|
|
17669
17736
|
return cells;
|
|
17670
17737
|
}
|
|
17671
|
-
function renderSideStarsCells(stars, rowIndex, xOffset, sideWidth, now) {
|
|
17738
|
+
function renderSideStarsCells(stars, meteors, rowIndex, xOffset, sideWidth, now) {
|
|
17672
17739
|
if (sideWidth <= 0) return [];
|
|
17673
17740
|
const cells = emptyCells(sideWidth);
|
|
17674
17741
|
placeStarsInCells(cells, stars, rowIndex, xOffset, xOffset + sideWidth, xOffset, now);
|
|
17742
|
+
placeMeteorsInCells(cells, meteors, rowIndex, xOffset, xOffset + sideWidth, xOffset, now);
|
|
17675
17743
|
return cells;
|
|
17676
17744
|
}
|
|
17677
17745
|
function clampCellsToWidth(content, width) {
|
|
@@ -17788,7 +17856,7 @@ function buildContentCells(prompt, agentName, state, elapsed, now, availableHeig
|
|
|
17788
17856
|
}
|
|
17789
17857
|
return rows;
|
|
17790
17858
|
}
|
|
17791
|
-
function buildFrameCells(prompt, agentName, state, topStars, bottomStars, sideStars, now, terminalWidth, terminalHeight) {
|
|
17859
|
+
function buildFrameCells(prompt, agentName, state, topStars, bottomStars, sideStars, now, terminalWidth, terminalHeight, topMeteors = [], bottomMeteors = [], sideMeteors = []) {
|
|
17792
17860
|
const elapsed = formatElapsed(now - state.startTime.getTime());
|
|
17793
17861
|
const availableHeight = Math.max(0, terminalHeight - 2);
|
|
17794
17862
|
const contentRows = buildContentCells(prompt, agentName, state, elapsed, now, availableHeight);
|
|
@@ -17797,20 +17865,24 @@ function buildFrameCells(prompt, agentName, state, topStars, bottomStars, sideSt
|
|
|
17797
17865
|
const remaining = Math.max(0, availableHeight - contentCount);
|
|
17798
17866
|
const topHeight = Math.max(0, Math.ceil(remaining / 2));
|
|
17799
17867
|
const bottomHeight = remaining - topHeight;
|
|
17868
|
+
const maxMeteorStartRow = Math.ceil(availableHeight * .75);
|
|
17869
|
+
const visibleTopMeteors = meteorsStartingBefore(topMeteors, 0, maxMeteorStartRow);
|
|
17870
|
+
const visibleSideMeteors = meteorsStartingBefore(sideMeteors, topHeight, maxMeteorStartRow);
|
|
17871
|
+
const visibleBottomMeteors = meteorsStartingBefore(bottomMeteors, topHeight + contentCount, maxMeteorStartRow);
|
|
17800
17872
|
const sideWidth = Math.max(0, Math.floor((terminalWidth - CONTENT_WIDTH) / 2));
|
|
17801
17873
|
const frame = [];
|
|
17802
|
-
for (let y = 0; y < topHeight; y++) frame.push(renderStarLineCells(topStars, terminalWidth, y, now));
|
|
17874
|
+
for (let y = 0; y < topHeight; y++) frame.push(renderStarLineCells(topStars, visibleTopMeteors, terminalWidth, y, now));
|
|
17803
17875
|
for (let i = 0; i < contentRows.length; i++) {
|
|
17804
|
-
const left = renderSideStarsCells(sideStars, i, 0, sideWidth, now);
|
|
17876
|
+
const left = renderSideStarsCells(sideStars, visibleSideMeteors, i, 0, sideWidth, now);
|
|
17805
17877
|
const center = centerLineCells(contentRows[i], CONTENT_WIDTH);
|
|
17806
|
-
const right = renderSideStarsCells(sideStars, i, terminalWidth - sideWidth, sideWidth, now);
|
|
17878
|
+
const right = renderSideStarsCells(sideStars, visibleSideMeteors, i, terminalWidth - sideWidth, sideWidth, now);
|
|
17807
17879
|
frame.push([
|
|
17808
17880
|
...left,
|
|
17809
17881
|
...center,
|
|
17810
17882
|
...right
|
|
17811
17883
|
]);
|
|
17812
17884
|
}
|
|
17813
|
-
for (let y = 0; y < bottomHeight; y++) frame.push(renderStarLineCells(bottomStars, terminalWidth, y, now));
|
|
17885
|
+
for (let y = 0; y < bottomHeight; y++) frame.push(renderStarLineCells(bottomStars, visibleBottomMeteors, terminalWidth, y, now));
|
|
17814
17886
|
frame.push(renderResumeHintCells(terminalWidth, state.interruptHint));
|
|
17815
17887
|
frame.push(emptyCells(terminalWidth));
|
|
17816
17888
|
return frame;
|
|
@@ -17826,8 +17898,11 @@ var Renderer = class {
|
|
|
17826
17898
|
topStars = [];
|
|
17827
17899
|
bottomStars = [];
|
|
17828
17900
|
sideStars = [];
|
|
17901
|
+
topMeteors = [];
|
|
17902
|
+
bottomMeteors = [];
|
|
17829
17903
|
cachedWidth = 0;
|
|
17830
17904
|
cachedHeight = 0;
|
|
17905
|
+
meteorFrequency;
|
|
17831
17906
|
prevCells = [];
|
|
17832
17907
|
prevTitle = null;
|
|
17833
17908
|
titleSaved = false;
|
|
@@ -17846,11 +17921,12 @@ var Renderer = class {
|
|
|
17846
17921
|
handleStopped = () => {
|
|
17847
17922
|
this.stop("stopped");
|
|
17848
17923
|
};
|
|
17849
|
-
constructor(orchestrator, prompt, agentName, onInterrupt) {
|
|
17924
|
+
constructor(orchestrator, prompt, agentName, onInterrupt, options = {}) {
|
|
17850
17925
|
this.orchestrator = orchestrator;
|
|
17851
17926
|
this.prompt = prompt;
|
|
17852
17927
|
this.agentName = agentName;
|
|
17853
17928
|
this.onInterrupt = onInterrupt;
|
|
17929
|
+
this.meteorFrequency = Math.max(0, Math.floor(options.meteorFrequency ?? DEFAULT_METEOR_FREQUENCY));
|
|
17854
17930
|
this.state = orchestrator.getState();
|
|
17855
17931
|
this.seedTop = Math.floor(Math.random() * 2147483646) + 1;
|
|
17856
17932
|
this.seedBottom = Math.floor(Math.random() * 2147483646) + 1;
|
|
@@ -17903,6 +17979,7 @@ var Renderer = class {
|
|
|
17903
17979
|
const availableHeight = Math.max(0, h - 2);
|
|
17904
17980
|
const remaining = Math.max(0, availableHeight - BASE_CONTENT_ROWS);
|
|
17905
17981
|
const topHeight = Math.max(0, Math.ceil(remaining / 2));
|
|
17982
|
+
const bottomHeight = Math.max(0, remaining - topHeight);
|
|
17906
17983
|
const proximityRows = 8;
|
|
17907
17984
|
const shrinkBig = (s, nearContentRow) => {
|
|
17908
17985
|
if (!nearContentRow || s.x < contentStart || s.x >= contentEnd) return s;
|
|
@@ -17918,6 +17995,8 @@ var Renderer = class {
|
|
|
17918
17995
|
this.topStars = generateStarField(w, h, STAR_DENSITY, this.seedTop).map((s) => shrinkBig(s, s.y >= topHeight - proximityRows));
|
|
17919
17996
|
this.bottomStars = generateStarField(w, h, STAR_DENSITY, this.seedBottom).map((s) => shrinkBig(s, s.y < proximityRows));
|
|
17920
17997
|
this.sideStars = generateStarField(w, Math.max(BASE_CONTENT_ROWS, availableHeight), STAR_DENSITY, this.seedSide);
|
|
17998
|
+
this.topMeteors = generateMeteorShower(w, topHeight, topHeight > 0 ? meteorCountForFrequency(this.meteorFrequency) : 0, this.seedTop + METEOR_SEED_OFFSET);
|
|
17999
|
+
this.bottomMeteors = generateMeteorShower(w, bottomHeight, bottomHeight > 0 ? meteorCountForFrequency(this.meteorFrequency) : 0, this.seedBottom + METEOR_SEED_OFFSET);
|
|
17921
18000
|
return true;
|
|
17922
18001
|
}
|
|
17923
18002
|
return false;
|
|
@@ -17928,7 +18007,7 @@ var Renderer = class {
|
|
|
17928
18007
|
const h = process$1.stdout.rows || 24;
|
|
17929
18008
|
const resized = this.ensureStarFields(w, h);
|
|
17930
18009
|
this.updateTerminalTitle(now);
|
|
17931
|
-
const nextCells = buildFrameCells(this.prompt, this.agentName, this.state, this.topStars, this.bottomStars, this.sideStars, now, w, h);
|
|
18010
|
+
const nextCells = buildFrameCells(this.prompt, this.agentName, this.state, this.topStars, this.bottomStars, this.sideStars, now, w, h, this.topMeteors, this.bottomMeteors);
|
|
17932
18011
|
if (this.isFirstFrame || resized) {
|
|
17933
18012
|
process$1.stdout.write("\x1B[H" + nextCells.map(rowToString).join("\n"));
|
|
17934
18013
|
this.isFirstFrame = false;
|
|
@@ -17959,6 +18038,7 @@ function slugifyPrompt(prompt) {
|
|
|
17959
18038
|
//#region src/cli.ts
|
|
17960
18039
|
const packageVersion = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8")).version;
|
|
17961
18040
|
const FORCE_EXIT_TIMEOUT_MS = 5e3;
|
|
18041
|
+
const MAX_METEOR_FREQUENCY = 5;
|
|
17962
18042
|
const GNHF_REEXEC_STDIN_PROMPT = "GNHF_REEXEC_STDIN_PROMPT";
|
|
17963
18043
|
const GNHF_REEXEC_STDIN_PROMPT_FILE = "GNHF_REEXEC_STDIN_PROMPT_FILE";
|
|
17964
18044
|
const GNHF_REEXEC_STDIN_PROMPT_DIR_PREFIX = "gnhf-stdin-";
|
|
@@ -17977,6 +18057,11 @@ function parseNonNegativeInteger(value) {
|
|
|
17977
18057
|
if (!Number.isSafeInteger(parsed)) throw new InvalidArgumentError("must be a safe integer");
|
|
17978
18058
|
return parsed;
|
|
17979
18059
|
}
|
|
18060
|
+
function parseMeteorFrequency(value) {
|
|
18061
|
+
const parsed = parseNonNegativeInteger(value);
|
|
18062
|
+
if (parsed > MAX_METEOR_FREQUENCY) throw new InvalidArgumentError(`must be between 0 and ${MAX_METEOR_FREQUENCY}`);
|
|
18063
|
+
return parsed;
|
|
18064
|
+
}
|
|
17980
18065
|
function parseOnOffBoolean(value) {
|
|
17981
18066
|
if (value === "on" || value === "true") return true;
|
|
17982
18067
|
if (value === "off" || value === "false") return false;
|
|
@@ -18053,10 +18138,19 @@ function initializeNewBranch(prompt, cwd, schemaOptions) {
|
|
|
18053
18138
|
const runId = createBranchWithSuffix(slugifyPrompt(prompt), cwd).split("/")[1];
|
|
18054
18139
|
return setupRun(runId, prompt, baseCommit, cwd, schemaOptions);
|
|
18055
18140
|
}
|
|
18141
|
+
function promptRunId(prompt) {
|
|
18142
|
+
return slugifyPrompt(prompt).split("/")[1];
|
|
18143
|
+
}
|
|
18144
|
+
function resumeCurrentBranchRun(prompt, cwd, schemaOptions) {
|
|
18145
|
+
const runId = promptRunId(prompt);
|
|
18146
|
+
if (!existsSync(join(cwd, ".gnhf", "runs", runId))) return null;
|
|
18147
|
+
ensureCleanWorkingTree(cwd);
|
|
18148
|
+
return resumeRun(runId, cwd, schemaOptions);
|
|
18149
|
+
}
|
|
18056
18150
|
function initializeCurrentBranchRun(prompt, cwd, schemaOptions) {
|
|
18057
18151
|
ensureCleanWorkingTree(cwd);
|
|
18058
18152
|
const baseCommit = getHeadCommit(cwd);
|
|
18059
|
-
return setupRun(createRunIdWithSuffix(
|
|
18153
|
+
return setupRun(createRunIdWithSuffix(promptRunId(prompt), cwd), prompt, baseCommit, cwd, schemaOptions);
|
|
18060
18154
|
}
|
|
18061
18155
|
function branchNameWithSuffix(branchName, suffix) {
|
|
18062
18156
|
return suffix === 0 ? branchName : `${branchName}-${suffix}`;
|
|
@@ -18264,13 +18358,13 @@ function readReexecStdinPrompt(env) {
|
|
|
18264
18358
|
}
|
|
18265
18359
|
}
|
|
18266
18360
|
const program = new Command();
|
|
18267
|
-
program.name("gnhf").description("Before I go to bed, I tell my agents: good night, have fun").version(packageVersion).argument("[prompt]", "The objective for the coding agent").option("--agent <agent>", `Agent to use (${AGENT_NAMES.join(", ")}, or acp:<target-or-command>)`).option("--max-iterations <n>", "Abort after N total iterations", parseNonNegativeInteger).option("--max-tokens <n>", "Abort after N total input+output tokens", parseNonNegativeInteger).option("--stop-when <condition>", "End when the agent reports this condition, after any commit-failure repair; resumes reuse it, pass a new value to overwrite or \"\" to clear").option("--prevent-sleep <mode>", "Prevent system sleep during the run (\"on\" or \"off\")", parseOnOffBoolean).option("--worktree", "Run in a separate git worktree (enables multiple agents on the same repo)", false).option("--current-branch", "Run on the current branch instead of creating a gnhf branch", false).option("--push", "Push the current branch after each successful iteration", false).option("--mock", "", false).action(async (promptArg, options) => {
|
|
18361
|
+
program.name("gnhf").description("Before I go to bed, I tell my agents: good night, have fun").version(packageVersion).argument("[prompt]", "The objective for the coding agent").option("--agent <agent>", `Agent to use (${AGENT_NAMES.join(", ")}, or acp:<target-or-command>)`).option("--max-iterations <n>", "Abort after N total iterations", parseNonNegativeInteger).option("--max-tokens <n>", "Abort after N total input+output tokens", parseNonNegativeInteger).option("--stop-when <condition>", "End when the agent reports this condition, after any commit-failure repair; resumes reuse it, pass a new value to overwrite or \"\" to clear").option("--prevent-sleep <mode>", "Prevent system sleep during the run (\"on\" or \"off\")", parseOnOffBoolean).option("--worktree", "Run in a separate git worktree (enables multiple agents on the same repo)", false).option("--current-branch", "Run on the current branch instead of creating a gnhf branch", false).option("--push", "Push the current branch after each successful iteration", false).option("--meteor-frequency <n>", "Meteor frequency from 0 to 5 (0 disables, 3 is default)", parseMeteorFrequency, 3).option("--mock", "", false).action(async (promptArg, options) => {
|
|
18268
18362
|
if (options.mock) {
|
|
18269
18363
|
const mock = new MockOrchestrator();
|
|
18270
18364
|
enterAltScreen();
|
|
18271
|
-
const renderer = new Renderer(mock, "let's minimize app startup latency without sacrificing any functionality", "
|
|
18365
|
+
const renderer = new Renderer(mock, "let's minimize app startup latency without sacrificing any functionality", "codex", () => {
|
|
18272
18366
|
mock.handleInterrupt();
|
|
18273
|
-
});
|
|
18367
|
+
}, { meteorFrequency: options.meteorFrequency });
|
|
18274
18368
|
renderer.start();
|
|
18275
18369
|
mock.start();
|
|
18276
18370
|
await renderer.waitUntilExit();
|
|
@@ -18358,7 +18452,14 @@ program.name("gnhf").description("Before I go to bed, I tell my agents: good nig
|
|
|
18358
18452
|
program.help();
|
|
18359
18453
|
return;
|
|
18360
18454
|
}
|
|
18361
|
-
|
|
18455
|
+
const existing = resumeCurrentBranchRun(prompt, cwd, buildResumeSchemaOptions(options.stopWhen, effectiveCommitMessage));
|
|
18456
|
+
if (existing) {
|
|
18457
|
+
runInfo = existing;
|
|
18458
|
+
effectiveStopWhen = existing.stopWhen;
|
|
18459
|
+
effectiveCommitMessage = existing.commitMessage;
|
|
18460
|
+
schemaOptions = buildSchemaOptions(effectiveStopWhen, effectiveCommitMessage);
|
|
18461
|
+
startIteration = getLastIterationNumber(existing);
|
|
18462
|
+
} else runInfo = initializeCurrentBranchRun(prompt, cwd, schemaOptions);
|
|
18362
18463
|
} else if (onGnhfBranch) {
|
|
18363
18464
|
const existingRunId = currentBranch.slice(5);
|
|
18364
18465
|
const existingMetadata = peekRunMetadata(existingRunId, cwd);
|
|
@@ -18487,7 +18588,7 @@ program.name("gnhf").description("Before I go to bed, I tell my agents: good nig
|
|
|
18487
18588
|
requestForceShutdown("SIGTERM");
|
|
18488
18589
|
};
|
|
18489
18590
|
enterAltScreen();
|
|
18490
|
-
const renderer = new Renderer(orchestrator, prompt, config.agent, handleSigInt);
|
|
18591
|
+
const renderer = new Renderer(orchestrator, prompt, config.agent, handleSigInt, { meteorFrequency: options.meteorFrequency });
|
|
18491
18592
|
renderer.start();
|
|
18492
18593
|
process$1.on("SIGINT", handleSigInt);
|
|
18493
18594
|
process$1.on("SIGTERM", handleSigTerm);
|