Minimal, responsive, transparent LLM coding assistant.
Not affiliated with Anthropic or Amazon. YACT is an independent, open-source, third-party tool. It is not made, endorsed, or supported by Anthropic PBC or Amazon Web Services. "Claude" and "Anthropic" are trademarks of Anthropic PBC, "AWS" and "Bedrock" are trademarks of Amazon.com, Inc.; they are used here only to describe which APIs this tool calls. For Anthropic's own products and documentation, go to anthropic.com and docs.claude.com.
- Assisted, not autonomous. YACT supports AI assisted software development, not AI driven software development. You decide what goes into the context and what the model is asked to do.
- Responsive. Each command is a single API call, so you get results in seconds rather than waiting on a multi-step agent loop.
- Reactive. YACT does what it is explicitly asked to do, and nothing more. It never explores your codebase or runs commands on its own initiative.
- Transparent. The full task context lives in a plain text file you can read and edit, and every response is logged verbatim.
YACT is a CLI tool. You assemble a task by hand, send it once, and get one response back.
The task context lives in a plain text file, .yact/context.txt, in your project
directory. It is a list of file paths, one per line. The contents of these files are sent
to the LLM together with your prompt.
You add files with y read (or y keyword), then run a prompt command such as ask,
plan, act or bash, passing your task prompt as an argument. Each of those makes
exactly one API call. Responses are parsed for code blocks; complete source files found in
the response are written to disk, and any prose outside code blocks is printed to the
terminal.
YACT asks the model to emit complete source files rather than incremental edits. This keeps the LLM interface simple — there are no editing tools to call, no patch formats to get wrong, and no partial-apply failures — and it lets YACT keep each request self-contained and cheap.
The trade-off is that an editable file must fit inside the model's output token limit.
Current Claude models allow a large output budget per response, but YACT's own default
(max_tokens) is 16000, so raise it if you work with larger files. See
Anthropic's model documentation for
the current per-model limits. Keeping source files to a few hundred lines is recommended
regardless.
If a response contains a code block that has only a file path comment and no content, YACT deletes that file from disk and removes it from the task context.
Every prompt command and query takes its prompt from one of two places:
- A prompt argument. The argument is the prompt, and the files in
.yact/context.txtare sent as context. Links inside the argument are not interpreted. - The saved plan. Without a prompt argument,
.yact/plan.mdis the prompt, and only the files linked in the plan are sent as context. A missing or empty plan is an error.
The plan workflow is described in Plan, then act.
If the plan contains Markdown links to local files, such as
[src/router/router.go](src/router/router.go), YACT sends the linked files. The links
become the context for that call. A link means exactly one thing: "send this file's content
to the model".
- Links to URLs, anchors (
#...) and protocol-relative targets are skipped with a warning; nothing is downloaded. - Links to missing files, unreadable files or directories are skipped with a warning.
- Duplicate links are sent once.
- If the plan contains no links, or none of them is usable, no context files are sent.
.yact/context.txtis neither used nor modified while a plan is the prompt, and files created by the response are not added to it.
This is what makes the plan → act workflow work: the plan prompt produces a Markdown
plan whose links point to the files each step needs, the plan is saved to
.yact/plan.md, and the next call without a prompt argument uses that plan as its prompt
(see Plan, then act).
Before every call YACT counts the lines of the prompt plus the lines of all files sent as
context (the files linked in the plan when the plan is the prompt, otherwise the files in
.yact/context.txt) and prints the total as Input lines: <n>. Only the text that is
actually sent is counted, so when the plan is the prompt, steps that are left out, whether
through --steps or because they are already done, are not counted. If the total exceeds
max_input_lines (default: 1000), the call is refused. Raise the limit permanently with
y config max_input_lines <n>, or for a single call with -m <n>.
YACT is a Swiss army knife for LLM assisted coding rather than a complete automated coding suite. It is deliberately narrower than a full agent:
- You select the context yourself. YACT will not go looking for the files a task needs, so you need to know your codebase.
- No MCP support, no tool calling, no multi-turn agent loop.
- File sizes are bounded by the model's output token limit, as described above.
- Two providers only: Anthropic's API and AWS Bedrock. There is currently no support for other providers or local models.
YACT is written in Go. Building from source means you run code you can read:
git clone https://github.com/agabor/yact.git
cd yact
go build -o y .
Then move y somewhere on your PATH — ~/.local/bin needs no elevated privileges:
mkdir -p ~/.local/bin
mv y ~/.local/bin/
There is also an install.sh script that builds the binary and installs it to
/usr/local/bin using sudo.
Release binaries are published as GitHub release artifacts, built from tagged commits in the repository. Download them from the releases page:
| Platform | Asset |
|---|---|
| Linux (x86-64) | yact-linux-amd64 |
| Windows (x86-64) | yact-windows-amd64.exe |
| macOS (Apple silicon) | yact-darwin-arm64 |
| macOS (Intel) | yact-darwin-amd64 |
Download the asset for your platform from the releases page, verify it against the checksum
published alongside it, make it executable, and place it on your PATH. On Linux and
macOS:
chmod +x yact-linux-amd64
mkdir -p ~/.local/bin
mv yact-linux-amd64 ~/.local/bin/y
Installing under ~/.local/bin keeps the binary in your own user account. If you prefer a
system-wide install under /usr/local/bin, that requires administrator privileges — only
do so once you are satisfied with what you downloaded.
On Windows, place yact-windows-amd64.exe in a directory on your PATH, or run it
directly from wherever you downloaded it.
Configure your Anthropic API key. Create the key yourself at
console.anthropic.com; it is written to ~/.yact/config
on your machine and used only for calls to Anthropic's API:
y config anthropic_api_key <your-own-anthropic-key>
Verify your configuration at any time:
y config
Download the official system prompts, then start a task:
y -d act
y new
y read main.go
y act "add a --version flag"
YACT is driven by system prompts. Every system prompt file in ~/.yact/systemprompts/
becomes a command. For example, if act.txt exists, you can run y act. Typical prompt
commands are ask, plan, act and bash, but you can add your own. Each prompt command
makes exactly one API call.
Download the official system prompts with the -d / --download flag. These are plain
text files fetched from the YACT repository; you can read them at any time in
~/.yact/systemprompts/:
y -d act
y -d plan
y -d ask
y -d bash
You can also write your own prompt files in ~/.yact/systemprompts/, or tailor the
official ones to your workflow. Run y help to see the list of currently available prompt
commands.
A prompt file may start with a line of the form flags: <letters>. Each letter enables the
short form of a global flag whenever that prompt command runs. That first line is not sent
to the model. For example, a prompt file beginning with:
flags: nc
behaves as if -n -c had been passed. Supported letters:
n—--no-write(ignored if-vis active)c— Claude Sonnet (ignored if you pass-cor-qyourself)q— Qwen Max on Bedrock (ignored if you pass-cor-qyourself)d—--downloadv—--validate-code(ignored if-nis active)p—--plan
Any other character is ignored. The official prompts use these defaults: act runs with
c1v (the 1 is not a supported letter and is ignored), ask with c2n, bash with
c1n, and plan with c2np (the 2 is ignored, p saves the response as the plan).
Create a fresh, empty task context:
y new
Attach files so the model can reference them:
y read main.go
y read "commands/*.go"
Glob patterns are supported. Directories are skipped, and files already in the context are
not added twice. The list is stored in .yact/context.txt.
Recursively scan the project and add every file containing a keyword to the task context:
y keyword Transaction
Hidden directories are skipped, and only files with indexed extensions are considered (see
y config ext below). Files already in the context are not added twice.
Run any prompt command with the task prompt as an optional argument:
y act "implement Foo"
y ask "is Foo buggy?"
y plan "add authentication"
y bash "find all TODO comments in Go files"
The prompt is sent together with the files in the task context. Without a prompt argument, the saved plan is used instead (see Prompt or plan). The prompt is not saved anywhere.
The response is parsed for code blocks. Complete source files found in the response are
written directly to your filesystem, and newly created files are automatically added to the
task context (when a prompt argument was given). Any text outside code blocks is printed to
the terminal. The raw response is always logged to .yact/buffer.txt.
Because responses are written to disk, run YACT inside a version-controlled working tree so
you can review and revert what it writes. Use --no-write to print the response instead of
writing files:
y -n act "implement Foo"
The plan prompt asks the model for a short Markdown plan. The plan has a # Goal section
and a ## Steps section with one ### [ ] N. <title> heading per step, and each step
changes exactly one file. Each step ends with a **Context:** line holding links to the
files needed for that step. With -p / --plan, the response is not processed as code; it
is saved to .yact/plan.md:
y -p plan "add authentication"
Then run a prompt command without a prompt argument:
y act
The plan is the prompt. Without --steps, the goal and all steps that are not ticked off
yet are sent; steps that are already done are left out, and so are their links. A plan
without steps is sent as a whole. The context is built only from the files linked in the
text that is sent; .yact/context.txt is not used or modified, and a plan without usable
links sends no context files. If .yact/plan.md is missing or empty, the call fails.
Passing a prompt argument ignores the plan.
Review or edit .yact/plan.md between the two steps if you want to adjust the plan.
With -s / --steps <selector>, only the selected steps are implemented, one call at a
time. The text before the first step (the goal) and the selected steps are sent; all other
steps are left out, and so are their links. The selector can be:
N— a single step, for example2N-M— a range of steps, for example2-4- a comma separated list of the above, for example
1,3,5-6 next— the first step that is not ticked off yet
y -s next act
y -s 1,3 act
--steps requires a plan, and cannot be combined with a prompt argument or with --plan.
Plans with duplicate step numbers, selectors that name steps missing from the plan, and
plans without steps are rejected. Selecting a step that is already done prints a warning,
and the step is sent again.
After a call has successfully written its response, the steps that were sent are marked
done in .yact/plan.md: ### [ ] 1. Title becomes ### [x] 1. Title. Without --steps
only the remaining unticked steps are sent and ticked; a plan without steps is sent whole.
When every step is already ticked, YACT prints All plan steps are done. and makes no
call. Steps are not ticked when -n is used or when the call fails. Untick a step by hand
to run it again.
Running a call with -p writes the response to .yact/plan.md, overwriting any existing
plan. Nothing is written to your source tree and the response is not validated in that
case. The plan is never deleted automatically; remove it when you no longer need it:
rm .yact/plan.md
With -v / --validate-code, the call fails if the response contains free text outside
code blocks or an incomplete code block. Nothing is written to disk in that case, although
the response is still logged to .yact/buffer.txt:
y -v act "implement Foo"
-v and -n are mutually exclusive when set through a prompt file's flags: line.
Call the LLM with no system prompt. The response is printed and never written to disk:
y query "explain what the keyword command does"
The task context is still sent. Without a prompt argument, query uses the saved plan and
its links, and honours -p and -s the same way prompt commands do.
Write the code blocks of the last response in .yact/buffer.txt to disk, for example after
a -n run:
y -n act "implement Foo"
y commit
With -v, the commit fails if the buffer contains free text or an incomplete code block.
-h, --help Show help message
-n, --no-write Do not write files, print response instead
-c, --claude <level> Use Claude model (1: Haiku, 2: Sonnet, 3: Opus, 4: Fable)
-q, --qwen <level> Use Qwen model on AWS Bedrock (1: Coder, 2: Max)
-d, --download Download the system prompt for the command
--no-progress Hide progress indicator
-v, --validate-code Fail if the response (or, for commit, the buffer) contains
free text or incomplete code blocks
-p, --plan Write the response to .yact/plan.md
-s, --steps <selector> Implement only the selected steps of .yact/plan.md (N, N-M,
a comma separated list such as 1,3,5-6, or next). Requires a
plan; cannot be combined with a prompt argument or with --plan.
Finished steps are ticked off after a successful write
-m, --max-input-lines <n> Set max input lines for the current command, without changing config
Flags come before the command:
y -c 3 ask "how does the parser work?"
y --claude 2 --no-progress plan "add authentication"
y -q 1 act "add a --version flag"
y -m 3000 act "add a --version flag"
y -p plan "add authentication"
y -s next act
Model flags override the configured model for a single invocation. Qwen level 1 selects
qnext and level 2 selects qmax. Model availability depends on your own Anthropic or AWS
account. When a flag is used, YACT prints the effective flags as Executing: y <flags> <command> before the call.
View current settings:
y config
Set configuration values:
y config claude_model sonnet
y config max_tokens 32000
y config max_input_lines 2000
Available configuration keys:
anthropic_api_key— your own Anthropic API key, stored locally (required for Claude models)claude_model— which model to use:fable,opus,sonnet,haiku,qmaxorqnext(default:haiku)bedrock_model— Bedrock model id used byqmax(default:qwen.qwen3-235b-a22b-2507-v1:0)bedrock_next_model— Bedrock model id used byqnext(default:qwen.qwen3-coder-30b-a3b-next-v1:0)aws_region— AWS region for Bedrock calls (default:us-west-2)aws_api_key— Bedrock API key, stored locally; when empty, the default AWS credential chain is used insteadmax_tokens— maximum output tokens per API call (default: 16000)max_input_lines— maximum number of lines of prompt plus context files sent in one call (default: 1000)
Note that max_tokens caps the size of what the model can write back. Since YACT generates
complete source files, this value bounds the size of the files it can edit. Raise it if
responses are being truncated; the ceiling is the model's own output limit.
Selecting qmax or qnext, either through configuration or the -q flag, routes the call
to AWS Bedrock instead of Anthropic. Authentication works in one of two ways:
- Set
aws_api_keyand YACT sends it as a bearer token, bypassing SigV4 signing. - Leave
aws_api_keyempty and YACT uses the standard AWS credential chain (environment variables, shared config, instance roles).
The region comes from aws_region, and the model id from bedrock_model (qmax) or
bedrock_next_model (qnext).
The y keyword command only scans files with recognized extensions. A default set of
common source file extensions is stored in .yact/extensions.txt. Add an extension with:
y config ext vue
Every API call prints the model used, call duration, input and output token counts, and an estimated cost in dollars. The estimate is calculated locally from published rates and is informational only — your actual billing is whatever Anthropic or AWS charges your account. A warning is shown if the response hit the output token limit and may be incomplete.
Global settings live in ~/.yact/:
config— API keys and model settings (JSON)systemprompts/— system prompt text files
Per-project state lives in .yact/ inside your project directory:
context.txt— the task context, one file path per linebuffer.txt— log of the last LLM responseplan.md— the saved plan written by-p; used as the prompt, and its links as the context, when a call is made without a prompt argumentextensions.txt— file extensions scanned by the keyword command
Add .yact/ to your .gitignore so task context and response logs are not committed.
y help
y --help
y -h
"Claude API key not configured"
- Set your key:
y config anthropic_api_key <your-own-anthropic-key>
"unable to load AWS configuration"
- Configure AWS credentials and region, or set a Bedrock key:
y config aws_api_key <your-own-key> - Check that
aws_regionmatches a region where the model is available
"input exceeds maximum number allowed lines"
- Start a smaller context with
y newand re-add only the files you need - Select fewer plan steps with
-s - Raise the limit for one call with
-m <n>, or permanently withy config max_input_lines <n>
"response contains free text outside code blocks" / "incomplete code block"
- These come from
-v/--validate-code. Rerun the command, or drop-vto accept free text. The rejected response is still available in.yact/buffer.txt.
"no plan found in .yact/plan.md, provide a prompt or create a plan with --plan"
- You ran a call without a prompt argument and there is no saved plan. Pass a prompt, or
create a plan with
y -p plan "<task>".
"--steps and --plan cannot be combined" / "--steps cannot be combined with a prompt argument"
--stepsworks on the saved plan only. Drop the prompt argument or the-pflag.
"step range ... does not match the plan" / "invalid step selector item"
- The selector names steps the plan does not contain, or is malformed. Use
N,N-M, a comma separated list, ornext, and check the numbers in.yact/plan.md.
"Warning: link '...' skipped: ..."
- A Markdown link in the plan points to a URL, a missing file, an unreadable file or a
directory, so it was not sent. Fix the link target in
.yact/plan.mdor remove the link. - Be aware that a plan ignores
.yact/context.txt; only the linked files are sent.
"No files found matching pattern"
- Check that the glob pattern matches existing files
- Quote glob patterns so your shell does not expand them first
- Use exact paths if glob patterns don't work
"no system prompt found for command"
- Download the missing system prompt:
y -d <command> - Or create the file manually in
~/.yact/systemprompts/
Truncated or incomplete responses
- Raise
max_tokens, or split the file you are editing into smaller ones
API errors
- Verify your API key is valid in the Anthropic or AWS console
- Check your internet connection
- Ensure your account has available credits
YACT is a local command-line program. It has no server component and no website that accepts input.
- Your API keys stay on your machine. They are stored in
~/.yact/configas plain JSON. YACT sends the Anthropic key only tohttps://api.anthropic.com, as thex-api-keyheader that Anthropic's API requires, and the AWS key only to the Bedrock endpoint for your configured region. They are never transmitted anywhere else. - You get your own keys. YACT never issues, requests, brokers, or collects API keys. Create an Anthropic key in your own account at console.anthropic.com, and manage AWS credentials in your own AWS account.
- No telemetry. YACT does not phone home, collect analytics, or report usage. The only
outbound network connections it makes are the API calls you explicitly trigger, and
system-prompt downloads when you pass
-d. Links to URLs in a plan are never fetched. - No background activity. YACT runs when you invoke it and exits. It installs no
service, daemon, or scheduled task, and modifies nothing outside
~/.yact/and the.yact/directory of the project you are working in. - You choose what is sent. Only the files you add with
y readory keyword(or link in your saved plan), plus the prompt you write, are included in a request. YACT never scans or uploads your codebase on its own initiative. - Auditable. The complete source is public. Every release is built from a tagged
commit in the repository, and every response is logged verbatim to
.yact/buffer.txt.
If you would rather not trust prebuilt binaries, build from source — it takes one command and is documented under Installation.
Open an issue at github.com/agabor/yact/issues. For anything security-sensitive, please report it privately through the repository's security advisory page rather than in a public issue.