mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
* feat(cli): save check, snapshot and render artifacts per revision * fix(cli): keep clean --snapshots inside the project A symlinked .hyperframes or artifacts folder was followed, so the command deleted snapshot and check files outside the project. * test(cli): keep check, snapshot, and render successful when recording fails A held history or a corrupt output registry warns and leaves the command result alone. * fix(cli): drop snapshot records when a replaced run is not recorded A reused --output rewrites the files even when history is busy. Those records are removed so the old revision does not keep the new pixels. The preview checkpoint stops waiting after five seconds. A bad PNG header no longer fails the snapshot. * fix(studio-server): keep the video-state comment share from rising The forget helper's doc comment pushed the file above its base share. * fix(cli): post the preview checkpoint and keep cleanup inside artifacts A preview checkpoint with no body was sent as GET, so Studio never ran it. Cleanup now requires the real path to stay under the artifacts folder. A failed follow-up drop does not warn twice. The studio-server unpacked budget covers the record-dropping helper. * docs(cli): shorten the snapshot skill notes The command examples already show range and composition. The prose only keeps the output path and the flags that are easy to misuse. * chore: leave package headroom for artifact cleanup * test(cli): compare artifact paths portably * style(cli): format portable artifact assertion
92 lines
3.9 KiB
Plaintext
92 lines
3.9 KiB
Plaintext
---
|
|
title: "Running the CLI from an agent harness"
|
|
description: "How an agent harness declares what it supports through HF_TOOL_CONTEXT, and what the CLI reports back."
|
|
---
|
|
|
|
An agent harness (Claude Code, Codex, your own) runs `hyperframes` commands on the agent's behalf.
|
|
`HF_TOOL_CONTEXT` lets the harness tell one invocation what it supports, so the CLI can do more for
|
|
it: report the images it produced, or wait its turn instead of racing another command in the same
|
|
project. Without the variable, every command behaves exactly as it does in a terminal.
|
|
|
|
```bash
|
|
export HF_TOOL_CONTEXT='{"version":1,"capabilities":{
|
|
"events": {"transport": {"type": "ndjson-file", "path": "/tmp/call-42/events.ndjson"}},
|
|
"project-lock": {"waitMs": 90000}
|
|
}}'
|
|
npx hyperframes snapshot --at 1,3
|
|
```
|
|
|
|
The harness sets the variable for one tool call, reads what the call produced, and removes its files.
|
|
|
|
## The declaration
|
|
|
|
| Field | Value |
|
|
| --- | --- |
|
|
| `version` | `1`. Any other version, or a value that is not JSON, is treated as no declaration. |
|
|
| `capabilities` | An object keyed by capability name. Each value configures that capability. |
|
|
|
|
The CLI ignores capability names it does not know, and a known capability whose value is invalid, so
|
|
a harness can declare capabilities newer than the CLI it runs. The variable carries data only: no
|
|
capability runs code the harness names.
|
|
|
|
## `events`: what a command produced
|
|
|
|
```json
|
|
{ "transport": { "type": "ndjson-file", "path": "/absolute/events.ndjson" } }
|
|
```
|
|
|
|
The CLI appends one JSON object per line to `path`. It never creates the parent directory, and a
|
|
write that fails prints a warning without failing the command. Read the file after the command
|
|
exits; several commands in one shell call append to the same file.
|
|
|
|
Each line is an event:
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"type": "artifact.created",
|
|
"command": "snapshot",
|
|
"artifact": { "role": "contact-sheet", "path": "/project/.hyperframes/artifacts/snapshots/…/contact-sheet.jpg", "mediaType": "image/jpeg" }
|
|
}
|
|
```
|
|
|
|
| Command | `role` | What it is |
|
|
| --- | --- | --- |
|
|
| `snapshot` | `frame` | Each captured frame (PNG) |
|
|
| `snapshot` | `contact-sheet` | Each page of the grid of frames made for review (JPEG) |
|
|
| `check` | `check-report` | The saved JSON report |
|
|
| `check` | `frame` | Each frame the browser check captured |
|
|
| `check` | `finding` | Each crop around a finding |
|
|
|
|
Paths are absolute and stay where the command saved them. What to do with an artifact is the
|
|
harness's decision: attach the contact sheet to the tool result, link the report, or ignore it.
|
|
Ignore event types and roles you do not know; new ones are added without a version change.
|
|
|
|
## `project-lock`: one browser command at a time
|
|
|
|
```json
|
|
{ "waitMs": 90000 }
|
|
```
|
|
|
|
`check` and `snapshot` take a lock on the project before they start a browser, and release it when
|
|
they finish. A second command waits up to `waitMs` milliseconds for the lock, then fails, naming the
|
|
command and process that hold it. A lock whose process has exited is taken over. A
|
|
`project.lock.break` left by a killed process is not: the timeout names that file and its process
|
|
id, and says to delete it to continue. The lock is the file `.hyperframes/project.lock`.
|
|
|
|
Choose `waitMs` below your tool call's own timeout, so a wait ends in the CLI's message rather than
|
|
the harness killing the call.
|
|
|
|
## Hooks that run code
|
|
|
|
Running your own command before or after a CLI command is not a `HF_TOOL_CONTEXT` capability and
|
|
never will be: anything that sets an environment variable could then run code. Such hooks, when they
|
|
exist, come only from configuration the person controls.
|
|
|
|
## Conformance
|
|
|
|
`packages/cli/src/utils/toolContext.test.ts` and `projectLock.test.ts` pin the parsing, event and
|
|
lock behavior above. A harness is correct when it sets the variable for each call it wants the
|
|
behavior on, reads `events` only after the call exits, and works the same when the CLI ignores a
|
|
capability.
|