AutoHotkey v2.1 +Console
A fork of AutoHotkey v2.1 that makes AHK behave like a real command-line program — stdout/stderr, exit codes, JSON diagnostics, and no GUI popups — so scripts can run headless in terminals, CI, and AI tooling.
What it is
Stock AutoHotkey is built around the desktop: errors pop up in a MsgBox, there's no real
stdout, and nothing returns a meaningful exit code. The +Console fork keeps the
language identical but adds a proper command-line surface. Scripts can print to stdout/stderr, run
fully headless (errors go to the shell instead of a dialog), emit machine-readable JSON diagnostics,
and return standard process exit codes. That turns AHK into something you can pipe, script in a
Makefile, run in CI, or hand to an LLM agent that reads the error output and fixes the code.
Why it matters
The whole point is the contrast. Same language, completely different relationship with the shell:
| Stock AHK v2 | +Console fork | |
|---|---|---|
| An error | blocks on a MsgBox dialog |
written to stderr, process exits |
| Exit code | always 0 |
0 ok · 10 runtime · 12 parse · 13 validate · 14 test fail |
| Output | GUI only | Print() → stdout · "*"/"**" streams |
| Tooling | hard to automate | JSON diagnostics for CI / agents to parse |
Features
Real streams
Print("...") writes a line to stdout; FileAppend "x", "*" / "**" target stdout / stderr directly.
Headless /Headless
Suppresses every dialog; errors and warnings go to stderr. Usable where there is no desktop at all.
Structured diagnostics /Diag=json
One JSON object per error/warning with severity, type (error class like TypeError), code, message, file, line, source, and stack. Machine-parseable.
Editor-style errors /ErrorStdOut[:color]
file (line) : ==> message, with the verbatim source line plus surrounding context and optional ANSI color on a terminal.
Exit codes
Shells and CI can branch on success vs. parse / runtime / test failure instead of guessing.
Subcommands
check script.ahk (syntax-validate) and test script.ahk (test runner), each with its own exit code.
Runtime eval
Eval(expr) plus a SyntaxError class, gated behind #EnableEval.
Source introspection
_ScriptGetLines() exposes the script's own source for programmatic context.
Exit codes
Every run ends with a standard process exit code, so a shell or CI step can react to exactly what happened:
# branch on the result, like any other CLI tool
AutoHotkey.exe /Headless build.ahk && echo "ok" || echo "failed ($?)"
Printing to streams
The language is unchanged, so this is just normal AHK v2 — it simply has somewhere to go now:
Command-line switches
| Switch | What it does |
|---|---|
/Headless | Suppress all dialogs; route errors and warnings to stderr. For servers, CI, and any desktop-less environment. |
/Diag=json | Emit one machine-readable JSON object per diagnostic (severity, type, code, message, file, line, source, stack). |
/ErrorStdOut | Editor-style human errors: file (line) : ==> message with source context. Append :color for ANSI color. |
# headless run, errors to stderr
AutoHotkey.exe /Headless deploy.ahk
# machine-readable diagnostics for an agent or CI to parse
AutoHotkey.exe /Diag=json /Headless deploy.ahk 2> diagnostics.ndjson
# editor-style errors with color in a terminal
AutoHotkey.exe /ErrorStdOut:color deploy.ahk
JSON diagnostics
With /Diag=json, each error or warning is emitted as a single JSON object — one per line —
instead of a dialog. A CI runner or an LLM agent can read this, point at the offending line, and act:
Fields: severity, type (the error class, e.g. TypeError), code, message, file, line, source (the verbatim line), and stack.
Subcommands
check syntax-validates a script without running it; test runs its tests. Each returns its own exit code, so they slot straight into a pipeline:
# validate syntax only (exit 12 on parse error)
AutoHotkey.exe check script.ahk
# run the test suite (exit 14 on test failure)
AutoHotkey.exe test script.ahk
# a tiny CI gate
AutoHotkey.exe check src.ahk && AutoHotkey.exe test src.ahk
Runtime eval & introspection
Opt-in with #EnableEval to evaluate AHK expressions at runtime; a dedicated
SyntaxError class reports malformed input. _ScriptGetLines() hands back the
script's own source for tools that need context around a line.
Why agents & CI care
Normal AHK assumes a human is sitting at a desktop watching dialog boxes. This fork assumes a program is on the other end — a shell, a CI runner, or an AI agent — and gives it the streams, exit codes, and structured output that program needs to actually understand what happened.
That is exactly the loop the CloudAHK service and the Opus 4.8 examples rely on: run a script, capture stdout/stderr and a real exit code, feed any structured error back to the model, and let it fix the code — no human-in-the-loop dialog box in the way.
Get it
The fork lives here — same language, console-grade surface: