Skip to content

Commit fc22eb2

Browse files
committed
Add commands
1 parent 03c49e5 commit fc22eb2

3 files changed

Lines changed: 322 additions & 0 deletions

File tree

‎assets/commands/corral.md‎

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# TAGLINE
2+
3+
Run a command and kill every process it starts
4+
5+
# TLDR
6+
7+
Run a **build with a 30-second wall-clock limit**
8+
9+
```corral --wall 30s -- ./build.sh```
10+
11+
Cap **stdout and stderr together** and write an **audit JSON** record
12+
13+
```corral --wall 5m --max-output 1M --json [run.json] -- make test```
14+
15+
Force **cgroup v2 enforced mode** with memory and process limits
16+
17+
```corral-enforced --wall 30s --mem 512M --pids 64 -- ./build.sh```
18+
19+
Stay in **fallback mode** (no cgroup) and still reap leftovers
20+
21+
```corral --cgroup-mode=fallback --wall 10s -- [command]```
22+
23+
**Inherit stdin** instead of connecting it to `/dev/null`
24+
25+
```corral --stdin inherit --wall 30s -- [command]```
26+
27+
Print the **version**
28+
29+
```corral --version```
30+
31+
# SYNOPSIS
32+
33+
**corral** [_options_] [**--**] _command_ [_args_...]
34+
35+
**corral-enforced** [_options_] [**--**] _command_ [_args_...]
36+
37+
# PARAMETERS
38+
39+
**--wall** _DURATION_
40+
> Wall-clock limit for the run. A duration is an integer with `ms`, `s`, `m`, or `h`; a bare integer is seconds
41+
42+
**--grace** _DURATION_
43+
> Time between SIGTERM and SIGKILL (default **2s**). **0** skips SIGTERM and sends SIGKILL immediately
44+
45+
**--verify-timeout** _DURATION_
46+
> Maximum time to drain and prove every leftover process has stopped after SIGKILL (default **2s**)
47+
48+
**--mem** _SIZE_
49+
> Memory limit. Enforced mode only. A size is an integer of bytes with optional **K**, **M**, or **G** (powers of 1024)
50+
51+
**--pids** _COUNT_
52+
> Maximum number of processes. Enforced mode only
53+
54+
**--max-output** _SIZE_
55+
> Combined stdout plus stderr byte cap. The run ends when the cap is reached
56+
57+
**--cgroup-mode** _MODE_
58+
> **auto** (default), **enforced**, or **fallback**. **auto** uses a cgroup v2 group when one can be created
59+
60+
**--cgroup-parent** _PATH_
61+
> Delegated cgroup under which corral creates per-run groups
62+
63+
**--stdin** _POLICY_
64+
> **null** (default: stdin is `/dev/null`) or **inherit**
65+
66+
**--json** _PATH_
67+
> Write one JSON audit record for the run to _PATH_ (mode, limits, why it ended, step times, leftover pids)
68+
69+
**--quiet**
70+
> Do not print the human summary line on stderr
71+
72+
**--version**
73+
> Print the version and exit
74+
75+
**--help**
76+
> Print usage and exit
77+
78+
**--**
79+
> End of options. Everything after it is the command, even if it starts with `-`
80+
81+
# DESCRIPTION
82+
83+
**corral** runs a command with an optional time limit and, when it returns, no process that the command started is still alive. It verifies that before it returns. If it cannot prove it, it exits **120**, overriding every other exit code.
84+
85+
Typical runners signal the direct child or its process group and then wait until the output pipes close. That fails when a daemon double-forks and calls `setsid()`, when a background process keeps stdout or stderr open, or when a process ignores SIGTERM. Leftover processes keep ports, file locks, and CPU, and the next run can fail because of them.
86+
87+
corral controls the full process tree:
88+
89+
- **Enforced mode** puts the command in its own **cgroup v2** group. The kernel keeps every descendant in that group, and one write to `cgroup.kill` stops all of them. **--mem** and **--pids** apply only in this mode. It needs a delegated cgroup. The **corral-enforced** wrapper starts one with `systemd-run --user --scope -p Delegate=yes` and then execs **corral --cgroup-mode=enforced**.
90+
- **Fallback mode** needs no cgroup. corral is a child subreaper, finds remaining processes through `/proc` (parent, process group, and session), and signals them through pidfds so a reused pid never gets the signal.
91+
92+
The run ends when the command exits, not when its pipes close. After each run, corral stops and reaps processes until none are left. In enforced mode the kernel must also report the group empty, and `rmdir` of the group must succeed.
93+
94+
The command is started in a new session so a signal to its group never reaches corral. Stdin is `/dev/null` unless **--stdin inherit** is set.
95+
96+
corral is not a security sandbox. It does not limit file access, network access, or privileges.
97+
98+
# EXIT CODES
99+
100+
**command's code**
101+
> The command exited on its own
102+
103+
**128+N**
104+
> Signal _N_ stopped the command, or corral itself received signal _N_ (130 for Ctrl-C)
105+
106+
**124**
107+
> The wall-clock limit expired
108+
109+
**121**
110+
> The memory limit was reached (enforced mode)
111+
112+
**122**
113+
> The output limit was reached
114+
115+
**126**, **127**
116+
> corral could not start the command (**127**: not found)
117+
118+
**125**
119+
> Setup failed or an option is not correct. The command did not start
120+
121+
**120**
122+
> corral could not prove that all processes stopped. This code overrides all others
123+
124+
# CAVEATS
125+
126+
Linux only. Needs Linux **5.11** or later, and **5.14** or later for enforced mode. Prebuilt binaries target x86-64 with glibc **2.36** or later.
127+
128+
The Homebrew formula and AUR packages named **corral** are ponylang's Pony dependency manager, not this process supervisor. Install from the GitHub release or build with CMake.
129+
130+
corral cannot see work the command starts outside its process tree (`systemd-run`, D-Bus, `at`). In enforced mode a process can leave the group if it writes to cgroupfs itself. In fallback mode corral cannot signal a setuid child and then exits **120**. If you stop corral with SIGKILL, only the direct child is sure to stop. There is no PTY support and no CPU-time limit.
131+
132+
# HISTORY
133+
134+
Written by Cardinal44. MIT licensed. Version **0.1.0** (2026-09-28).
135+
136+
# SEE ALSO
137+
138+
[timeout](/man/timeout)(1), [systemd-run](/man/systemd-run)(1), [prlimit](/man/prlimit)(1), [cgexec](/man/cgexec)(1), [kill](/man/kill)(1)
139+
140+
# RESOURCES
141+
142+
```[Source code](https://github.com/Cardinal44/corral)```
143+
144+
<!-- verified: 2026-09-30 -->

‎assets/commands/geneva.md‎

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# TAGLINE
2+
3+
Command-line video editor and compositor
4+
5+
# TLDR
6+
7+
**Trim** a clip (copied to a keyframe unless `--exact`)
8+
9+
```geneva trim [match.mp4] -o [goal.mp4] --from [41:10] --to [41:40]```
10+
11+
**Join** clips with a one-second crossfade
12+
13+
```geneva concat [day1.mp4] [day2.mp4] -o [trip.mp4] --crossfade 1s```
14+
15+
**Convert** for the web encode table
16+
17+
```geneva convert [talk.mov] -o [talk.mp4] --for web```
18+
19+
**Burn** subtitles into the picture
20+
21+
```geneva subtitles [talk.mp4] -o [talk-subbed.mp4] --burn [talk.srt]```
22+
23+
**Render** a JSON timeline (titles and graphics as HTML/CSS)
24+
25+
```geneva render [edit.json] -o [out.mp4]```
26+
27+
**Probe** a file's streams, duration, and colour tags
28+
29+
```geneva probe [talk.mp4]```
30+
31+
Write a **still** from a video
32+
33+
```geneva frame [talk.mp4] -o [thumb.jpg] --at 12s --width 640```
34+
35+
Print the **built-in manual** (for scripts and agents)
36+
37+
```geneva guide```
38+
39+
# SYNOPSIS
40+
41+
**geneva** [**--format** _human_|_json_] _subcommand_ [_options_]
42+
43+
**geneva** **trim** _input_ **-o** _file_ [**--from** _time_] [**--to** _time_ | **--duration** _time_] [_encode-options_]
44+
45+
**geneva** **concat** _input_... **-o** _file_ [**--crossfade** _time_ | **--fade** _time_] [_encode-options_]
46+
47+
**geneva** **convert** _input_ **-o** _file_ [_size-options_] [_encode-options_]
48+
49+
**geneva** **render** _timeline.json_ **-o** _file_|_dir_ [_encode-options_]
50+
51+
**geneva** **probe** _file_
52+
53+
# PARAMETERS
54+
55+
**--format** _human_|_json_
56+
> Global. **json** prints one JSON document on stdout. In **human** mode diagnostics go to stderr. Default **human**
57+
58+
Times accept `1.5`, `1.5s`, `1500ms`, `45f` (frames at the source rate), or `00:00:01.5`.
59+
60+
**trim**
61+
> Cut a range. **--from** starts the keep (default: beginning). **--to** or **--duration** ends it (default: end of the file). Copied by default, with the cut moved back to a keyframe; **--exact** for the exact frame
62+
63+
**concat**
64+
> Join two or more inputs back to back. Identical stream parameters are copied; anything else is rendered. **--crossfade** _TIME_ dissolves (constant-power audio). **--fade** _TIME_ dips through **--fade-color** (black default)
65+
66+
**convert**
67+
> Re-encode, optionally changing container, codec, size, or rate. **--width** / **--height** (one keeps the aspect, rounded even). **--fps**. **--fit** `contain`|`cover`|`fill`. **--crop** `X,Y,WxH` or centred `WxH` (pixels or percentages). **--speed** _FACTOR_ (`2` twice as fast; pitch follows)
68+
69+
**resize**
70+
> **convert** with **--width** or **--height** required (or **--crop**)
71+
72+
**overlay** _input_ _overlay_ **-o** _file_
73+
> Image or video (without its audio) over the input. **--at** `top-right` (default), `top-left`, `bottom-left`, `bottom-right`, `center`. **--margin** (default 24 px). **--scale**. **--opacity** 0–1. **--start** / **--duration**
74+
75+
**audio**
76+
> One of **--extract** (audio file; **--speech** writes 16 kHz mono), **--mute**, **--replace** _FILE_, or **--mix** _FILE_ [**--gain** _DB_]
77+
78+
**subtitles**
79+
> One of **--add** _FILE_ (repeatable, with **--language** codes in order), **--burn** _FILE_ (`.srt`, `.vtt`, or word-timed `.json`; **--position**, **--style** JSON, **--highlight** _COLOR_, **--fit**), or **--extract** [**--track** _N_]
80+
81+
**render** _timeline_ **-o** _file_|_dir_
82+
> Render a JSON document. The container comes from the extension unless the document sets it. With an `outputs` map, **-o** is a directory
83+
84+
**frame** _timeline_|_video_ **-o** _picture_
85+
> One PNG or JPEG. **--at** _TIME_ or **--frame** _N_. **--width** / **--height**. Default output `frame.png`
86+
87+
**validate** _timeline_
88+
> Parse and check. **--probe** also opens media assets. **--assets** _DIR_ is the asset root (default: the timeline's directory)
89+
90+
**probe** _file_
91+
> Container, duration, streams, sizes, rates, rotation, and colour tags
92+
93+
**schema**
94+
> Print the JSON Schema of the current timeline format
95+
96+
**targets**
97+
> Print the **--for** table (device and platform encode presets)
98+
99+
**guide** [_TOPIC_] [**--list**]
100+
> Built-in manual. No topic: the agent guide. Topics: `agents`, `timeline`, `cli`, `errors`, `color`, `architecture`
101+
102+
**explain** _CODE_ [**--list**]
103+
> What a diagnostic code means (any case). **--list** prints every code
104+
105+
Shared encode flags on the verbs (and several on **render**):
106+
107+
**-o** _FILE_
108+
> Output path. The extension selects the container
109+
110+
**--crf** _N_
111+
> Constant quality; lower is better. Useful range about 18–30 for H.264/H.265. Forces a re-encode
112+
113+
**--preset** _NAME_
114+
> Encoder preset, `ultrafast` to `veryslow`. Forces a re-encode
115+
116+
**--codec** _NAME_
117+
> `h264`, `h265`, `vp9`, `av1`, `prores`, `dnxhd`, `png`, `mjpeg`. Default: the container's usual codec
118+
119+
**--for** _TARGET_
120+
> Encode for a destination: `phone`, `tablet`, `desktop`, `tv`, `web`, `youtube`, `instagram`, `tiktok`, `podcast`, `x`, `linkedin`, `email`. **--quality** `best`|`good`|`eco` (default **good**). **--budget** _SIZE_ (for example `25MB`)
121+
122+
**--exact**
123+
> Frame-accurate cuts. With H.264 and system x264, a smart cut copies untouched GOPs and re-encodes only around cuts and overlays
124+
125+
**--renderer** _auto_|_cpu_|_gpu_
126+
> Who composites frames. **auto** (default) uses a hardware GPU if one is present, else the CPU. Copied streams are copied either way
127+
128+
**--show-timeline**
129+
> Print the compiled JSON document instead of rendering
130+
131+
**--no-audio**
132+
> Write no audio track
133+
134+
Also: **--max-bitrate**, **--audio-codec**, **--audio-bitrate**, **--sample-rate**, **--channels**, **--keep-hdr**, **--chunks** `N`|`auto`, **--fill** `bars`|`blur`, **--profile**, **--tune**, **--keyframe-interval**, **--fixed-keyframes**.
135+
136+
# DESCRIPTION
137+
138+
**geneva** is a command-line video editor. Everyday verbs (`trim`, `concat`, `convert`, and the rest) are compiled into a JSON timeline and rendered through the same path as **geneva render**. Titles and graphics are HTML and CSS, drawn by geneva's own layout engine — no browser, Playwright, or filtergraph.
139+
140+
A document names the format version in `"geneva"` (current **1.1**; a `"1.0"` document is read as it is). Assets are media files or HTML. Layers hold clips; clips can be video, audio, HTML, captions, or colour. Each frame is computed from its timestamp, so a render is deterministic. HDR sources are tone-mapped to SDR unless **--keep-hdr**.
141+
142+
The planner picks the cheapest output mode: **copy** (packets copied), **copy-picture**, **smart** (H.264 bytes copied where the picture is untouched), **direct** (decode to encode without the compositor), or **render** (full composite). Errors are reported before rendering, with a code and a JSON path, for example `error[E200]: unknown asset "crad"`. **geneva explain E302** prints what a code means.
143+
144+
Codecs come from FFmpeg's libraries, bundled in the binary. H.264 uses a hardware encoder when one is allowed, else the system's **x264**, else bundled OpenH264. Smart cut and smaller H.264 files need x264 on the system (`libx264` on Debian/Ubuntu, `brew install x264` on macOS, or `GENEVA_X264` / a `libx264-*.dll` beside `geneva.exe` on Windows). H.265 is hardware-only.
145+
146+
Markup supports flexbox and block layout, absolute positioning, gradients, `box-shadow`, `filter: blur()`, `clip-path: polygon()`, `mix-blend-mode`, `background-clip: text`, web fonts shipped as assets, and CSS `@keyframes` played as written. Not supported: CSS grid, floats, transitions, static `transform` (transforms come from animations), and JavaScript. An unsupported declaration is reported by name and skipped.
147+
148+
`--format json` works on every command. Exit **0** on success, **1** if the timeline is invalid, **2** for a usage error, **3** if rendering or encoding failed.
149+
150+
# CAVEATS
151+
152+
This **geneva** is geneva-render's video editor, not Georgetown's network-evasion toolkit of the same name.
153+
154+
No GUI and no hosted service. One binary for Linux (x64, arm64), macOS (Apple silicon), and Windows (x64). The install script is a curl-to-shell download of a GitHub release.
155+
156+
OpenH264 is bundled because x264 is GPL; without x264, smart cut is off and H.264 files are larger. VideoToolbox and NVENC at constant quality, and bundled OpenH264 always, ignore **--max-bitrate**; the report says so. `--budget` puts VideoToolbox in bitrate mode.
157+
158+
There is no fixed average bitrate, CBR, or two-pass encode: video is constant quality under an optional ceiling.
159+
160+
# HISTORY
161+
162+
Written by Francesco Benetti. MIT licensed. First public release **1.0.0** (2026-09-25); current **1.1.0** (2026-09-28), timeline format **1.1**.
163+
164+
# SEE ALSO
165+
166+
[ffmpeg](/man/ffmpeg)(1), [ffprobe](/man/ffprobe)(1), [melt](/man/melt)(1), [handbrakecli](/man/handbrakecli)(1), [whisper](/man/whisper)(1)
167+
168+
# RESOURCES
169+
170+
```[Source code](https://github.com/geneva-render/geneva)```
171+
172+
```[Homepage](https://genevarender.com)```
173+
174+
```[Documentation](https://github.com/geneva-render/geneva/blob/main/docs/cli.md)```
175+
176+
<!-- verified: 2026-09-30 -->

‎assets/commands/index.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,7 @@ core-validate-commit.md
14151415
coredumpctl.md
14161416
corepack.md
14171417
coreutils.md
1418+
corral.md
14181419
cosign.md
14191420
cotp.md
14201421
cotton.md
@@ -2613,6 +2614,7 @@ gemtopbm.md
26132614
gemtopnm.md
26142615
genact.md
26152616
gendesk.md
2617+
geneva.md
26162618
genfstab.md
26172619
genhtml.md
26182620
genid.md

0 commit comments

Comments
 (0)