Hania Code

Hania Code settings

An agent gets Hania Code from its settings. Open the agent, go to its Tools tab, turn on Use Hania Code in the Hania Code card, and save. It works for both Agents and Autonomous Agents. There is no tool to create or assign.

Agents made from the Coding Expert template come with Hania Code already on.

Turning it on doesn't choose a computer. Hania Code works in conversations started with hania on your computer, which you can then continue in the console, and in the agent's runs and team work while hania is open with that agent. See where it works. On Free the setting can be switched on, but no computer can connect, so it does nothing there.

The settings

In the consoleFieldWhat it does
Use Hania Codecode_enabledGives the agent Hania Code. Off by default.
What runs without askingcode_permission_modeHow much the agent does on its own. See modes.
Safety-check modelcode_auto_modelAuto mode only: the model its check runs on. Empty means the agent's own model.
Rulescode_permissionsAllow, ask, or deny specific changes. See rules.
Hookscode_hooksYour own commands that run before or after each change. See hooks.

The mode, rules and hooks only show while Hania Code is on. Turning it off and saving clears them.

Modes

The mode says how much the agent does without asking you first.

ModeWhat happens
ManualEvery change and command asks first. This is the default.
Accept editsFile changes run without asking. Commands still ask, and so does anything touching .git, .claude, shell profiles, or package configs.
PlanThe agent researches and proposes, and changes nothing. If it tries, the result tells it the session is in plan mode.
AutoChanges and commands run without asking, but a model checks each one first. If the check flags an action, or can't check it, the action doesn't run and asks you instead. See auto mode's check. That check is a model call, so it costs tokens and is billed like any other.

Rules are checked before the mode, and a deny always wins. So a rule can keep one command asking, or refuse it outright, whatever the mode says.

A single chat can run in its own mode: in the terminal client, Shift+Tab or /mode changes the mode for that chat, which overrides the agent's setting there. The console shows which mode a chat is in, and can't change it.

Approvals

Five actions change something, and only these can ask for approval: write (create or replace a file), edit (change part of a file), apply_patch (a change across several files), bash (run a command), and bash_start (start a command in the background).

Everything else runs without asking and isn't affected by rules or hooks: reading and searching (read, glob, grep), loading a skill (skill), and bash_output, bash_input, and bash_kill, which only work with a background command that was already approved.

Whether a change asks depends on the mode, the built-in defaults, and your rules. When it asks, the turn pauses and an approval card shows what the change would do:

ActionThe card shows
write"Approve writing to <path>?" and a diff of the file.
edit"Approve editing <path>?" and a diff of the file.
apply_patch"Approve applying this patch?" and a diff of every file in the patch. A file the patch deletes shows as a single delete <path> line.
bash"Approve running this command?" and the command.
bash_start"Approve running this command in the background?" and the command.

The diff comes from git diff on your computer. If git isn't installed there, there is no diff; the console then shows the change itself - the file content, the old and new text, or the patch - so you can still review it.

You can approve, approve with edits, or deny with a reason, and the agent continues from your decision. When you edit, only these parts of the change can be edited: the path and content of a write; the path, old text, new text, and replace-all of an edit; the patch; or the command. The kind of action can't be changed.

Approving a change doesn't bypass your Before hooks or deny rules. If one of them stops a change you approved, the agent is told that the change was approved but didn't run, and why.

In the terminal client, /auto answers cards for you for the rest of that session only. The mode is what decides whether a card is created at all.

Auto mode's check

In auto mode, each change and command is checked by a model before it runs. Most pass, and the call in the chat says Allowed by auto mode. If the check thinks an action is risky, it doesn't run, and you get a normal approval card instead. The card starts with what the check found, for example "Auto mode flagged this [Scope]: …", followed by the reason. The call in the chat shows the same note.

The check names the kind of risk it found, such as Data Exfiltration, Scope, Remote Code, Production Change, Mass Deletion, Security Weakening, or Untrusted Instructions. If the check itself fails, the card says auto mode could not check this, and why. Either way, nothing has run yet.

The card works like any other. Approving runs the action straight away without checking it again, but your deny rules and hooks still apply. Denying it, or letting it expire, works the same as on any card.

Don't ask again

Some cards offer a second way to approve, such as "Approve, don't ask again (run npm test)". Taking it approves the change and lets that exact file or command run without a card for the rest of that chat. It's offered only when the rule can be stated exactly, so it doesn't appear for a patch across several files, or where the target has a * or a ? in it.

These remembered approvals belong to the one chat, not to the agent, and the console shows how many a chat has next to its computer and folder. They're cleared from the terminal client. Nothing about them changes your rules, which still apply.

A remembered approval is checked before auto mode. So if you pick "don't ask again" on a card that auto mode flagged, that file or command runs from then on without a card and without auto mode's check, for the rest of the chat.

Runs with nobody watching. In autonomous runs, Hania Code's changes are blocked unless the agent has Allow destructive actions in autonomous runs turned on. Reads are never blocked. With that allowed, a change that would ask for approval pauses the run and waits in the review queue, unless the mode or an allow rule lets it through. Where a turn can't pause at all - a JSON (non-streaming) API send, the website widget, or a message from Messenger, Instagram, WhatsApp, Telegram, Slack or SMS - a change that would ask isn't run, and the agent is told so.

Rules

Rules decide which changes run, which ask, and which are refused. They're applied after the built-in defaults, which let safe read-only commands (like ls or git status) run without asking, deny destructive ones (like rm -rf /), and ask for everything else. Rules are checked in order and the last matching rule wins, so put broad rules first and exceptions after them.

Each rule has three parts:

PartWhat it matches
Action (permission)Which of the five actions the rule is about: write, edit, apply_patch, bash, or bash_start. Leave it empty, or use *, for all five.
Pattern (pattern)Required. It's checked against the file path for write and edit, and against the command for bash and bash_start. A patch has no single target, so only * matches apply_patch.
Decision (action)allow runs it without asking, ask shows the approval card, and deny refuses it.

In both the action and the pattern, * matches any run of characters and ? matches a single character. Matching is case-sensitive. So bash* covers both bash and bash_start, and apply_* covers apply_patch.

  • You can't list two actions in one rule. edit|write is read literally, matches nothing, and is refused - use two rules instead.
  • The action has to match at least one of the five. A value that matches none of them, such as Bash or read, is refused when you save.
  • An allow rule never lets through a command that contains &&, |, ;, >, or similar, so an allowed command can't be used to smuggle in another one.

For example, to let the agent run the tests and edit Markdown freely, stop it pushing, and keep it away from .env files:

[
  { "permission": "bash",  "pattern": "npm test*", "action": "allow" },
  { "permission": "bash",  "pattern": "git push*", "action": "deny" },
  { "permission": "edit",  "pattern": "*.md",      "action": "allow" },
  { "permission": "write", "pattern": "*.env",     "action": "deny" },
  { "permission": "edit",  "pattern": "*.env",     "action": "deny" }
]

In the console each rule is a row in the Hania Code card. If a rule isn't valid, saving is refused with a message that names it, for example rule 2: pattern is required (use * for everything).

Hooks

Hooks run your own commands around each change. A Before hook (PreToolUse) runs before the change, and if it exits with an error the change is blocked. An After hook (PostToolUse) runs after it, and its output is shown to the agent - a natural place for a linter, so the agent hears about problems in the code it just wrote.

FieldWhat it does
matcherWhich actions the hook runs for: one action, several joined with | (such as edit|write), or empty or * for all five. Unlike rules, hooks do accept |.
commandThe command to run. Required.
timeoutSeconds to allow. Leave it empty, or use 0, for the default of 60. There's no upper limit, and negative values are refused.

Hooks run on the same computer as the change, in the conversation's working folder, as a login shell (bash -lc). They run after the change is approved, and they don't ask for approval themselves.

Three environment variables are set before the hook runs: HANIA_HOOK_EVENT, HANIA_TOOL_ACTION, and HANIA_TOOL_TARGET. You can use them in the hook's command itself, and every command and program it runs sees them too, so one hook can behave differently per action or per file.

For example, in a Go project, an After hook with the matcher edit|write that runs the linter on each file the agent writes or edits:

golangci-lint run "$HANIA_TOOL_TARGET"

The same hook as it's stored in the agent's settings:

{
  "PostToolUse": [
    { "matcher": "edit|write",
      "command": "golangci-lint run \"$HANIA_TOOL_TARGET\"",
      "timeout": 60 }
  ]
}

For anything longer than a line, point the hook at a script in the project (such as ./scripts/after-edit.sh) and make it executable with chmod +x.

Through the API

The four fields go in the agent body on create and update, and come back inside the agent's settings on read. See Bots for the details.