You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
4.6 KiB
101 lines
4.6 KiB
|
2 months ago
|
# gnhf CLI reference
|
||
|
|
|
||
|
|
**This file is a cache, not the source of truth.** Verify with `gnhf --help` before relying on a
|
||
|
|
flag; the roster and options change between releases. Captured against **gnhf v0.1.49**.
|
||
|
|
|
||
|
|
Normally you should not call `gnhf` directly — use `scripts\start-run.ps1`, which adds the preflight
|
||
|
|
checks and the guaranteed finalize step. This reference exists for reading the flags the wrapper
|
||
|
|
passes and for diagnosing a run.
|
||
|
|
|
||
|
|
## Install
|
||
|
|
|
||
|
|
The skill **vendors its own copy** — you should not need a global install:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
npm install gnhf --prefix "$env:USERPROFILE\.scout\m-skills\lights-out\vendor"
|
||
|
|
```
|
||
|
|
|
||
|
|
That produces `vendor\node_modules\gnhf\dist\cli.mjs`, which the scripts run via `node`. Only `node`
|
||
|
|
needs to be on PATH; the npm-generated `gnhf` / `gnhf.cmd` / `gnhf.ps1` shims are irrelevant here
|
||
|
|
(they are 28-line launchers that resolve paths relative to their own location, so they cannot be
|
||
|
|
moved or copied anywhere useful).
|
||
|
|
|
||
|
|
Resolution order is `$env:LIGHTS_OUT_GNHF` → vendored → `gnhf` on PATH.
|
||
|
|
|
||
|
|
On this machine, `registry.npmjs.org` is TLS-intercepted and fails with
|
||
|
|
`ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE`. Use the configured Microsoft proxy registry — that is the
|
||
|
|
default, so a plain `npm install` works; do **not** pass `--registry=https://registry.npmjs.org`.
|
||
|
|
|
||
|
|
A global `npm install -g gnhf` still works as a fallback, but nothing in the skill requires it.
|
||
|
|
|
||
|
|
## Flags
|
||
|
|
|
||
|
|
| Flag | Notes |
|
||
|
|
|---|---|
|
||
|
|
| `--agent <agent>` | `claude`, `codex`, `rovodev`, `opencode`, `copilot`, `pi`, `cursor`, or `acp:<target-or-command>` |
|
||
|
|
| `--model <model>` | Overrides `agentModel.<agent>` from config |
|
||
|
|
| `--max-iterations <n>` | Abort after N iterations |
|
||
|
|
| `--max-tokens <n>` | Abort after N total input+output+cache tokens |
|
||
|
|
| `--max-rate-limit-wait <dur>` | Abort after this much cumulative usage-limit wait (`30m`, `2h`, `0`) |
|
||
|
|
| `--fallback-model <model>` | Retry a Claude usage-limit rejection with this model instead of waiting |
|
||
|
|
| `--stop-when <condition>` | Natural-language completion condition; survives resume. `""` clears it |
|
||
|
|
| `--prevent-sleep <on\|off>` | Keep the machine awake. Always `on` for overnight runs |
|
||
|
|
| `--worktree` | Run in a separate git worktree, enabling parallel runs on one repo |
|
||
|
|
| `--current-branch` | Commit on the current branch instead of creating `gnhf/<runId>` |
|
||
|
|
| `--push` | Push after each successful iteration |
|
||
|
|
| `--meteor-frequency <0-5>` | TUI meteors. The wrapper sets `0` (no TTY, so it is only log noise) |
|
||
|
|
| `--mock` | **TUI demo only.** Replays canned iterations, does no git work, does not exit. Never use it to validate a real run |
|
||
|
|
|
||
|
|
## Run identity
|
||
|
|
|
||
|
|
Deterministic, derived from the prompt — so a run is findable months later without guessing:
|
||
|
|
|
||
|
|
```
|
||
|
|
slug = prompt.toLowerCase()
|
||
|
|
.replace(/[^a-z0-9]+/g,'-')
|
||
|
|
.replace(/^-+|-+$/g,'')
|
||
|
|
.slice(0,20)
|
||
|
|
.replace(/-+$/,'')
|
||
|
|
hash = sha256(prompt).hex.slice(0,6)
|
||
|
|
runId = "<slug>-<hash>"
|
||
|
|
branch = "gnhf/<runId>"
|
||
|
|
```
|
||
|
|
|
||
|
|
On collision gnhf appends `-1`, `-2`, …, so the predicted id may not be the final one.
|
||
|
|
`Resolve-LightsOutRunDir` in `scripts\lib.ps1` handles that.
|
||
|
|
|
||
|
|
## Artifacts
|
||
|
|
|
||
|
|
Per run, in `<repo>\.gnhf\runs\<runId>\` (gitignored by gnhf, so it never pollutes the branch):
|
||
|
|
|
||
|
|
| File | Contents |
|
||
|
|
|---|---|
|
||
|
|
| `prompt.md` | The objective as given |
|
||
|
|
| `notes.md` | The agent's own iteration log — **claims, not evidence** |
|
||
|
|
| `end-state.json` | `status`, `stopCondition`, `agentError`, `iterations`, `successCount`, `failCount`, `endedAt` |
|
||
|
|
| `gnhf.log` | JSONL lifecycle log with timings and full `error.cause` chains |
|
||
|
|
| `iteration-<n>.jsonl` | Raw agent stream per iteration. Large; never copied to the vault |
|
||
|
|
| `base-commit` | Commit the run branched from |
|
||
|
|
| `stop-when` | Persisted stop condition |
|
||
|
|
|
||
|
|
## Behaviors that break unattended runs
|
||
|
|
|
||
|
|
Both are enforced by the wrapper's preflight; know them when diagnosing a failure.
|
||
|
|
|
||
|
|
1. **Launching from a `gnhf/*` branch** prompts interactively to overwrite/continue, and hard-fails
|
||
|
|
when stdin is not a TTY: *"Cannot show the overwrite prompt because stdin is not interactive."*
|
||
|
|
2. **An empty prompt with a non-TTY stdin** makes gnhf read the prompt *from* stdin and block
|
||
|
|
forever.
|
||
|
|
|
||
|
|
Also: gnhf requires a clean working tree, never force-pushes, never auto-pulls, and commits each
|
||
|
|
successful iteration separately so a night can be reviewed or reverted one change at a time.
|
||
|
|
|
||
|
|
## Docs
|
||
|
|
|
||
|
|
Upstream project: <https://github.com/kunchenguid/gnhf> (`README.md`, `VISION.md`).
|
||
|
|
|
||
|
|
The vendored package also ships its own README locally — no network needed:
|
||
|
|
`vendor\node_modules\gnhf\README.md`.
|
||
|
|
|
||
|
|
This skill does **not** depend on a local clone of the gnhf source repo.
|