AI.sh

A simple shell script agent
AI.sh

aish

           ,     ,
          (\____/)
           (_oo_)
             (O)        --  ai.sh
           __||__    \)
        []/______\[] /
        / \______/ \/
       /    /__\
      (\   /____\

Idea

How simple, lightweight and reliable can an agent be?

Solution

  • One shell script.
  • Use tried and tested linux programs like curl and jq.
  • Log file is simple so you can read it, and it is used for agent context.
  • Just give the agent shell access. No special commands, no context bloat.
  • Fast
  • This repo has 2 files.

Usage

Ask the agent a question (no quotes needed for simple text):

$ ./ai.sh what is the capital of Japan?
The capital of Japan is Tokyo.
$ ./ai.sh what is 2 plus 2
2 plus 2 is 4.
$ ./ai.sh write a hello world program in python. save it in ~/
I've created a Python hello world program at ~/hello.py:

```python
print("Hello, World!")

You can run it with python3 ~/hello.py.


With options:

```sh
$ ./ai.sh -v what is 2 plus 2
[loaded /home/user/.aish/log.jsonl — 3 messages, $0.0001 spent]
[step 1] (reasoning) The user wants to know 2 plus 2.
[done] 2 plus 2 is 4.
2 plus 2 is 4.
[finished — 1 steps, $0.0001 spent]
$ ./ai.sh -m gpt-4o "write a hello world program in python. save it in ~/"
I've created a Python hello world program at ~/hello.py:

```python
print("Hello, World!")

You can run it with python3 ~/hello.py.


```sh
$ ./ai.sh -R what is the capital of France
The capital of France is Paris.

The agent can run shell commands, read files, and execute multi-step
tasks. Context is saved and resumed on subsequent calls.

Command mode

Describe a command in English. The LLM generates the shell command,
prints it, and runs it in your terminal:

$ ./ai.sh -c show me all files including hidden ones
$ ls -a
.  ..  .git  .gitignore  README.md  ai.sh
$ ./ai.sh -c find all python files modified this week
$ find . -name '*.py' -mtime -7
./scripts/build.py
./src/main.py
$ ./ai.sh -c show me disk usage sorted by size
$ du -sh * | sort -rh
4.0M    ai.sh
2.0M    README.md

Autonomous mode

Give the agent a goal and let it run until done or budget exhausted:

$ ./ai.sh -a "explore the codebase and summarize the architecture"
[autonomous mode — goal: explore the codebase and summarize the architecture]
[step 1] $ ls -la
[step 2] $ cat ai.sh | head -50
[step 3] $ wc -l ai.sh
[done] This is a single-file shell script AI agent. It uses curl to call
an LLM API and jq to parse JSON. The script has three main parts: config
loading, an agent loop that calls the API and executes tool calls, and
a logger that writes append-only JSON lines. No build step required.
[finished — 3 steps, $0.0003 spent]

Initialize a local agent

By default, aish stores everything globally in ~/.aish/. To create a
self-contained agent for a specific project:

$ ./ai.sh -i
Initialized /home/user/myproject/.aish
  Edit /home/user/myproject/.aish/config.json to change model, budget, etc.
  Edit /home/user/myproject/.aish/system_prompt.txt to customize the agent's instructions.

This creates a .aish/ directory in the current folder with its own
config, system prompt, and log. While .aish/ exists, all storage is
local to that directory. Remove it to return to global mode.

Piping

The agent’s answer goes to stdout; status messages go to stderr. So you
can pipe the answer into other commands:

$ ./ai.sh what is the capital of Japan | wc -w
5
$ ./ai.sh list all python files in this dir | grep test
./test_runner.py
./test_config.py
$ ./ai.sh what is 2+2 > answer.txt
$ cat answer.txt
2 + 2 is 4.

You can also pipe input in. If no message is given on the command line,
stdin becomes the message. If both are given, stdin is appended:

$ echo "explain this error" | ./ai.sh
The error message indicates a missing semicolon at the end of line 12.
Add a `;` after the closing brace to fix it.
$ cat error.log | ./ai.sh explain this error
Looking at the error log, there are three issues:

1. Line 5: NullPointerException — the variable `config` was never
   initialized before use.
2. Line 12: FileNotFound — the path `/etc/app.conf` doesn't exist on
   this system.
3. Line 18: Timeout — the API call took longer than 30 seconds.

The root cause is likely the missing config file. Create it and the
other errors should resolve.
$ git diff | ./ai.sh -c generate a commit message
$ git commit -m "Fix: handle empty config file gracefully

- Add null check before reading config
- Fall back to defaults when config is missing
- Log warning when using fallback values"

Quick start

# 1. Install dependencies
sudo apt install curl jq coreutils    # Debian/Ubuntu

# 2. Add your API key (get one from https://ppq.ai)
cat > ~/.aish.conf <<'EOF'
DEFAULT_API_KEY="sk-your-key-here"
EOF
chmod 600 ~/.aish.conf

# 3. Run it
./ai.sh what is the capital of Japan

That’s it. No build step, no install script, no daemon.

Options

Short Long Description
-c --cmd Command mode (generate and run a shell command)
-a --autonomous Autonomous mode (run until done or budget exhausted)
-i --init Create local .aish/ with defaults, exit
-x --clear Clear the log file and exit
-v --verbose Show status lines
-m --model Override model
-k --api-key API key (or set PPQ_API_KEY)
-C --max-cost Override max cost (USD)
-s --max-steps Override max steps
-t --timeout Override overall timeout (seconds)
-T --cmd-timeout Override per-command timeout (seconds)
-r --resume Resume from existing log (default: yes)
-R --no-resume Start fresh (ignore existing log)
-h --help Show help

Configuration

API key

Create ~/.aish.conf with your key:

cat > ~/.aish.conf <<'EOF'
DEFAULT_API_KEY="sk-your-key-here"
EOF
chmod 600 ~/.aish.conf

This file lives in your home directory, outside the repo, and is never
committed. Any DEFAULT_* variable from ai.sh can be overridden there.

Config priority

Settings are resolved in this order (first match wins):

  1. CLI flags (-m, -C, -s, etc.)
  2. Local .aish/config.json (if .aish/ exists in current directory)
  3. Global ~/.aish/config.json
  4. ~/.aish.conf shell vars
  5. Built-in defaults in ai.sh

Storage

Global mode (default): ~/.aish/ holds config, system prompt, and
log. The agent has shared global memory — conversations from any
directory are logged to the same file and resumed on subsequent calls.

Local mode: Run ./ai.sh -i to create a .aish/ in the current
directory. While it exists, that directory uses its own config, prompt,
and log instead of the global ones.

Dependencies

  • curl
  • jq
  • coreutils (date, mkdir, chmod, head, cat, printf, mktemp, timeout, sync, basename, sleep, wc, tail, sed, grep)
# Debian / Ubuntu
sudo apt install curl jq coreutils

# Fedora / RHEL
sudo dnf install curl jq coreutils

# Arch
sudo pacman -S curl jq coreutils

# macOS (Homebrew — coreutils provides GNU versions like `timeout`)
brew install curl jq coreutils

Log format

Each line in log.jsonl is JSON with a source field:

source event who
user user_input you
model response the AI
aish exec script ran a command
aish api_error script detected an error

Warning

This agent has full shell access. It can run any command on your
system — read files, write files, delete data, install software, make
network requests. There are no sandboxing or permission restrictions.

Run it only on a computer, VM, or Qube that is dedicated to agent use.
Do not run it on a machine with sensitive data or credentials you cannot
afford to lose.


Write a comment