Update README.md
Browse files
README.md
CHANGED
|
@@ -8,7 +8,7 @@ dependencies: gcc, libcurl, bc, cJSON
|
|
| 8 |
persistence: shadowclaw.bin
|
| 9 |
---
|
| 10 |
|
| 11 |
-
# Shadowclaw
|
| 12 |
|
| 13 |
<div style="max-width: 100%; overflow-x: auto; background: #f6f8fa; padding: 4px; border-radius: 4px;">
|
| 14 |
<pre style="font-family: 'Courier New', monospace; font-size: clamp(4px, 2vw, 10px); line-height: 1.2; margin: 0;">
|
|
@@ -35,246 +35,179 @@ Low-power edge nodes: self-hosted persistent AI, no cloud.
|
|
| 35 |
|
| 36 |
---
|
| 37 |
|
| 38 |
-
## Repository Structure
|
| 39 |
-
|
| 40 |
-
```
|
| 41 |
-
shadowclaw/
|
| 42 |
-
├── shadowclaw.c # main program: arena, tools, LLM glue, event loop
|
| 43 |
-
├── Makefile # simple build file
|
| 44 |
-
├── cJSON.c # lightweigt JSON parser (from cJSON library)
|
| 45 |
-
└── cJSON.h # cJSON header
|
| 46 |
-
```
|
| 47 |
-
|
| 48 |
-
---
|
| 49 |
-
|
| 50 |
## Features
|
| 51 |
|
| 52 |
-
- **
|
| 53 |
-
- **
|
| 54 |
-
- **
|
| 55 |
-
- **
|
| 56 |
-
- **
|
| 57 |
-
- **
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
---
|
| 60 |
|
| 61 |
-
## Requirements
|
| 62 |
-
|
| 63 |
-
- Linux (developed on Debian, should work on most Unix‑likes)
|
| 64 |
-
- `gcc`, `make`, `libcurl4-openssl-dev`, `bc`
|
| 65 |
-
- [Ollama](https://ollama.com/) running locally (default `http://localhost:11434`) with a model pulled (e.g. `llama3.2`)
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
``
|
|
|
|
| 73 |
|
| 74 |
---
|
| 75 |
|
| 76 |
-
##
|
| 77 |
-
|
| 78 |
-
- **Change Ollama endpoint/model**: edit `ollama_endpoint` and `ollama_model` in `shadowclaw.c`.
|
| 79 |
-
|
| 80 |
-
Find this line (507) in the shadowclaw.c file:
|
| 81 |
-
|
| 82 |
-
```bash
|
| 83 |
-
// --------------------------------------------------------------------
|
| 84 |
-
// Main (with slash commands from v1.2.2)
|
| 85 |
-
// --------------------------------------------------------------------
|
| 86 |
-
int main(int argc, char **argv) {
|
| 87 |
-
const char *state_file = "shadowclaw.bin";
|
| 88 |
-
const char *ollama_endpoint = "http://localhost:11434";
|
| 89 |
-
const char *ollama_model = "qwen2.5:0.5b"; // change as needed
|
| 90 |
-
```
|
| 91 |
-
|
| 92 |
-
Adjust the model endpoint in "ollama_model = "qwen2.5:0.5b";" to meet your model.
|
| 93 |
|
| 94 |
-
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
### Shadow Arena
|
| 101 |
-
|
| 102 |
-
All dynamic data lives in a single `realloc`‑ed block.
|
| 103 |
-
A `ShadowHeader` is stored **immediately before** the user‑visible pointer.
|
| 104 |
-
This header holds capacity, used length, a magic number, and a dirty flag.
|
| 105 |
-
|
| 106 |
-
```
|
| 107 |
-
+-------------------+---------------------+
|
| 108 |
-
| ShadowHeader | payload (blobs) |
|
| 109 |
-
+-------------------+---------------------+
|
| 110 |
-
^
|
| 111 |
-
`- pointer returned to user
|
| 112 |
-
```
|
| 113 |
-
|
| 114 |
-
### Blob Format
|
| 115 |
-
|
| 116 |
-
Each item (system prompt, user message, tool result, etc.) is stored as:
|
| 117 |
-
|
| 118 |
-
```
|
| 119 |
-
+------------+------+------+-----------------+
|
| 120 |
-
| BlobHeader | kind | id | payload (bytes) |
|
| 121 |
-
+------------+------+------+-----------------+
|
| 122 |
```
|
| 123 |
|
| 124 |
-
|
| 125 |
-
- The payload is arbitrary data (null‑terminated strings for most kinds).
|
| 126 |
-
|
| 127 |
-
### Persistence
|
| 128 |
|
| 129 |
-
|
| 130 |
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
-All conversations and tool results are automatically saved to `shadowclaw.bin` and reloaded on restart.
|
| 134 |
-
|
| 135 |
-
---
|
| 136 |
-
|
| 137 |
-
# Updated 3/3/2026: Shadowclaw v1.3
|
| 138 |
-
|
| 139 |
-
### Built‑in Slash Commands
|
| 140 |
-
|
| 141 |
-
Type any of these commands directly at the `>` prompt – they are handled without invoking the LLM.
|
| 142 |
-
|
| 143 |
-
| Command | Description |
|
| 144 |
-
|-----------|-------------|
|
| 145 |
-
| `/help` | Show this help message. |
|
| 146 |
-
| `/tools` | List all available tools (shell, file I/O, HTTP, math, `list_dir`). |
|
| 147 |
-
| `/state` | Display current arena memory statistics (capacity, used bytes, dirty flag). |
|
| 148 |
-
| `/clear` | Clear the conversation history while retaining the system prompt. |
|
| 149 |
-
| `/chat` | Remind you that you are already in chat mode (the default behaviour). |
|
| 150 |
-
| `/exit` | Quit Shadowclaw. |
|
| 151 |
-
|
| 152 |
-
## Build
|
| 153 |
|
| 154 |
```bash
|
| 155 |
-
|
|
|
|
|
|
|
| 156 |
```
|
| 157 |
|
| 158 |
-
|
| 159 |
-
make clean && make
|
| 160 |
-
```
|
| 161 |
-
|
| 162 |
-
## Run
|
| 163 |
|
| 164 |
```bash
|
| 165 |
-
|
|
|
|
| 166 |
```
|
| 167 |
|
| 168 |
-
|
| 169 |
|
| 170 |
-
|
| 171 |
|
| 172 |
-
```
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
ShadowClaw ready. Type your message (Ctrl-D to exit)
|
| 176 |
-
/help
|
| 177 |
-
Shadowclaw commands:
|
| 178 |
-
/help Show this help
|
| 179 |
-
/tools List available tools
|
| 180 |
-
/state Show arena memory stats
|
| 181 |
-
/clear Clear conversation history (keeps system prompt)
|
| 182 |
-
/chat Remind you that chat mode is active
|
| 183 |
-
/exit Exit Shadowclaw
|
| 184 |
-
```
|
| 185 |
|
| 186 |
-
|
| 187 |
|
| 188 |
-
|
| 189 |
|
| 190 |
-
|
| 191 |
|
| 192 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
| 194 |
---
|
| 195 |
|
| 196 |
-
##
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
|
| 204 |
-
-
|
| 205 |
|
| 206 |
-
|
| 207 |
|
| 208 |
-
|
| 209 |
|
| 210 |
```json
|
| 211 |
-
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
```
|
| 213 |
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
-
|
| 217 |
-
-
|
| 218 |
-
- **Lightweight Design** – no complex argument schemas, no extra JSON nesting. The entire tool call is tiny.
|
| 219 |
-
- **Args are always a single string** to keep things simple.
|
| 220 |
-
- **Multiple values are encoded with delimiters** (like newline) – the tool and LLM agree on the format.
|
| 221 |
-
- **Shadowclaw’s niche** is minimalism: a single binary with persistent memory, running anywhere, with just enough tools to be genuinely useful.
|
| 222 |
|
| 223 |
-
|
| 224 |
|
| 225 |
---
|
| 226 |
|
| 227 |
-
##
|
| 228 |
-
|
| 229 |
-
Shadowclaw is designed for **minimal, self‑contained AI agents** running on resource‑constrained or air‑gapped systems.
|
| 230 |
-
Its toolset is deliberately small but powerful enough to automate many tasks without spawning heavy processes.
|
| 231 |
|
| 232 |
-
|
| 233 |
-
|------|--------------|--------------|------------------|
|
| 234 |
-
| `shell` | Executes any shell command | `"ls -la /home"` | Automate system maintenance, run scripts, control services on a headless Raspberry Pi or embedded Linux device. |
|
| 235 |
-
| `read_file` | Reads a file from disk | `"/etc/passwd"` | Inspect configuration files, read logs, retrieve data for the LLM to analyse – all without a web interface. |
|
| 236 |
-
| `write_file` | Writes content to a file (args: `filename\ncontent`) | `"notes.txt\nBuy milk"` | Create notes, write configuration files, save results – perfect for offline data logging. |
|
| 237 |
-
| `http_get` | Fetches a URL (via libcurl) | `"https://api.example.com/data"` | Retrieve weather, fetch RSS feeds, call local REST APIs – even on devices with no browser, just a network stack. |
|
| 238 |
-
| `math` | Evaluates an expression using `bc` | `"2 + 2 * 5"` | Let the LLM do arithmetic, unit conversions, or simple calculations without relying on external tools. |
|
| 239 |
-
| `list_dir` | Lists directory contents | `"/home/user"` | Explore filesystem, find documents, check available storage – all natively, without forking a shell. |
|
| 240 |
|
| 241 |
-
-
|
| 242 |
-
|
| 243 |
-
##
|
|
|
|
|
|
|
| 244 |
|
| 245 |
-
|
| 246 |
-
- **Tool used:** `shell` + `write_file`
|
| 247 |
-
- **Flow:** LLM asks to read a temperature sensor via a shell script, then logs the value to a file.
|
| 248 |
-
- **Why Shadowclaw?** Runs in <200KB RAM, no Python, no bloat. Persistent memory keeps the last readings.
|
| 249 |
|
| 250 |
-
|
| 251 |
-
- **Tool used:** `http_get` + `math` + `read_file`
|
| 252 |
-
- **Flow:** Engineer asks for a component value calculation; LLM fetches a local datasheet via HTTP, reads a config file, does the math, and writes a report.
|
| 253 |
-
- **Why Shadowclaw?** No cloud, no internet required. All data stays on the machine.
|
| 254 |
|
| 255 |
-
##
|
| 256 |
-
- **Tool used:** `shell` + `list_dir`
|
| 257 |
-
- **Flow:** Network admin asks for a list of active interfaces; LLM runs `ifconfig` and parses the output, then suggests a config change.
|
| 258 |
-
- **Why Shadowclaw?** Tiny binary fits in router storage (often just a few MB). Uses curl for local API calls.
|
| 259 |
|
| 260 |
-
|
| 261 |
-
-
|
| 262 |
-
|
| 263 |
-
|
|
|
|
| 264 |
|
| 265 |
---
|
| 266 |
|
| 267 |
-
##
|
| 268 |
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
|
|
|
|
|
|
|
|
|
| 276 |
|
| 277 |
-
## License
|
| 278 |
|
| 279 |
-
|
| 280 |
-
cJSON is also MIT licensed.
|
|
|
|
| 8 |
persistence: shadowclaw.bin
|
| 9 |
---
|
| 10 |
|
| 11 |
+
# Shadowclaw v3.4 (Testing)
|
| 12 |
|
| 13 |
<div style="max-width: 100%; overflow-x: auto; background: #f6f8fa; padding: 4px; border-radius: 4px;">
|
| 14 |
<pre style="font-family: 'Courier New', monospace; font-size: clamp(4px, 2vw, 10px); line-height: 1.2; margin: 0;">
|
|
|
|
| 35 |
|
| 36 |
---
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
## Features
|
| 39 |
|
| 40 |
+
- **🧠 Local LLM integration** – works with any Ollama model (default: `tinyllama:1.1b`).
|
| 41 |
+
- **🔧 Built‑in tools** – `file_read`, `file_write`, `http_get`, `math`, `list_dir`, `shell` (disabled by default), and more.
|
| 42 |
+
- **⏰ Cron jobs** – schedule recurring tasks using `@every N[s/m/h]`, `@hourly`, `@daily`, `@weekly`.
|
| 43 |
+
- **🌐 Webhooks** – trigger HTTP POST calls on tool execution or cron events.
|
| 44 |
+
- **🎓 Dynamic skills** – create reusable multi‑step workflows without recompiling.
|
| 45 |
+
- **💾 Core memory** – persistent key‑value storage (JSON) that survives across sessions.
|
| 46 |
+
- **📜 Soul file** – Markdown export of all memories (conversation, skills, crons, webhooks, core memory).
|
| 47 |
+
- **🎨 Colored TUI** – optional GNU readline support for line editing and history.
|
| 48 |
+
- **⚡ Thread‑safe** – cron jobs run in a separate thread, tool calls are queued.
|
| 49 |
+
- **🛡️ Security** – path sandboxing, domain allowlist, shell opt‑in, dry‑run mode.
|
| 50 |
|
| 51 |
---
|
| 52 |
|
| 53 |
+
## 📦 Requirements
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
+
- **Linux / macOS / WSL** (tested on Ubuntu 22.04, Kali)
|
| 56 |
+
- **Ollama** (running locally) – optional, the agent can run in `--no-llm` mode
|
| 57 |
+
- **Dependencies**:
|
| 58 |
+
- `libcurl` (HTTP requests)
|
| 59 |
+
- `libpthread` (threading)
|
| 60 |
+
- `libreadline` (optional, for TUI enhancements)
|
| 61 |
+
- `gcc` or `clang` with C99 support
|
| 62 |
|
| 63 |
---
|
| 64 |
|
| 65 |
+
## Installation + Launch
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
+
*Put all files into a single folder on your system*
|
| 68 |
|
| 69 |
+
```bash
|
| 70 |
+
cd ~/shadowclaw (The folder you put the files in)
|
| 71 |
+
make clean && make
|
| 72 |
+
./start.sh
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
```
|
| 74 |
|
| 75 |
+
## Setup your local Ollama model
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
+
*Shadowclaw is set to use qwen2.5:0.5b as a default, to change this:*
|
| 78 |
|
| 79 |
+
Find line 633 in the shadowclaw.c file:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
```bash
|
| 82 |
+
static const char *ollama_endpoint = "http://localhost:11434";
|
| 83 |
+
static const char *ollama_model = "qwen2.5:0.5b"; (Change this to desired model)
|
| 84 |
+
static long llm_connect_timeout = 15;
|
| 85 |
```
|
| 86 |
|
| 87 |
+
Also line 16 in the start.sh file:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
```bash
|
| 90 |
+
OLLAMA_ENDPOINT="${OLLAMA_ENDPOINT:-http://localhost:11434}"
|
| 91 |
+
OLLAMA_MODEL="${OLLAMA_MODEL:-qwen2.5:0.5b}" (Change this to desired model)
|
| 92 |
```
|
| 93 |
|
| 94 |
+
---
|
| 95 |
|
| 96 |
+
### First start
|
| 97 |
|
| 98 |
+
- The agent creates `shadowclaw.bin` (binary state) and a folder `shadowclaw_data/` containing `shadowsoul.md`.
|
| 99 |
+
- If Ollama is not reachable, it automatically falls back to `--no-llm` mode.
|
| 100 |
+
- A default heartbeat cron job (`@every 120s`) is added automatically to keep the soul file updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
+
---
|
| 103 |
|
| 104 |
+
## Interactive Commands
|
| 105 |
|
| 106 |
+
Shadowclaw understands both natural language (sent to the LLM) and slash commands.
|
| 107 |
|
| 108 |
+
| Command | Description |
|
| 109 |
+
|---------|-------------|
|
| 110 |
+
| `/help` | Show help and list all commands. |
|
| 111 |
+
| `/tools` | List available built‑in tools. |
|
| 112 |
+
| `/state` | Show arena memory usage and soul file stats. |
|
| 113 |
+
| `/clear` | Erase conversation history (keeps system prompt and core memory). |
|
| 114 |
+
| `/exit` | Quit the agent. |
|
| 115 |
+
| `/loop <schedule> <tool> [args]` | Schedule a recurring task. Examples:<br>`/loop 30m http_get https://example.com`<br>`/loop daily math "1+1"` |
|
| 116 |
+
| `/crons` | List all scheduled cron jobs. |
|
| 117 |
+
| `/webhooks` | Show registered webhooks. |
|
| 118 |
+
| `/skills` | List dynamic skills. |
|
| 119 |
+
| `/compact` | Manually compact the arena (remove deleted blobs). |
|
| 120 |
+
| `/soul` | Display information about `shadowsoul.md`. |
|
| 121 |
|
| 122 |
---
|
| 123 |
|
| 124 |
+
## 🛠️ Tools
|
| 125 |
+
|
| 126 |
+
Tools are invoked by the LLM during the “plan” phase. Each tool is described in the LLM prompt with its parameters and an example.
|
| 127 |
+
|
| 128 |
+
| Tool | Description | Example args |
|
| 129 |
+
|------|-------------|---------------|
|
| 130 |
+
| `file_read` | Read a file (max 10 MB, path must be inside CWD). | `notes.txt` |
|
| 131 |
+
| `file_write` | Write content to a file (overwrites). | `output.txt Hello world` |
|
| 132 |
+
| `http_get` | HTTP GET to an allowed domain (see `allowed_domains` in source). | `https://example.com/data` |
|
| 133 |
+
| `math` | Evaluate arithmetic expression. | `(2+3)*4` |
|
| 134 |
+
| `list_dir` | List directory contents. | `.` or `/home/user` |
|
| 135 |
+
| `webhook_add` | Register a webhook (JSON: `{"url":"...","event":"..."}`). | `{"url":"http://...","event":"tool:http_get"}` |
|
| 136 |
+
| `cron_add` | Add a cron job (JSON: `{"schedule":"...","tool":"...","args":"..."}`). | `{"schedule":"@every 30m","tool":"math","args":"1+1"}` |
|
| 137 |
+
| `cron_list` | List all cron jobs. | (none) |
|
| 138 |
+
| `cron_remove` | Remove cron jobs containing a substring in their JSON representation. | `@every` |
|
| 139 |
+
| `skill_add` | Create a dynamic skill (JSON with `name`, `desc`, `steps` array, optionally `interpreter_command`). | See below. |
|
| 140 |
+
| `skill_run` | Run a skill by name. | `weather London` |
|
| 141 |
+
| `list_skills` | List all available skills. | (none) |
|
| 142 |
+
| `update_core_memory` | Merge JSON object into core memory. | `{"user_name":"Alice","preferences":{"theme":"dark"}}` |
|
| 143 |
+
| `recall` | Search conversation history for a keyword. | `project` |
|
| 144 |
+
| `heartbeat` | Internal (used by cron). | (none) |
|
| 145 |
+
|
| 146 |
+
> **Security:** The `shell` tool is compiled out by default. To enable it, add `-DENABLE_SHELL_TOOL` to `CFLAGS` and understand the risks.
|
| 147 |
|
| 148 |
+
---
|
| 149 |
|
| 150 |
+
## Dynamic Skills
|
| 151 |
|
| 152 |
+
Skills are sequences of tool calls stored in the arena as `BLOB_KIND_SKILL`. Example creation:
|
| 153 |
|
| 154 |
```json
|
| 155 |
+
{
|
| 156 |
+
"name": "weather",
|
| 157 |
+
"desc": "Get weather for a city",
|
| 158 |
+
"steps": [
|
| 159 |
+
{"tool": "http_get", "args": "https://wttr.in/{0}"},
|
| 160 |
+
{"tool": "file_write", "args": "/tmp/weather.txt {result}"}
|
| 161 |
+
]
|
| 162 |
+
}
|
| 163 |
```
|
| 164 |
|
| 165 |
+
Placeholders supported:
|
| 166 |
+
- `{args}` – the whole argument string passed to `skill_run`
|
| 167 |
+
- `{0}`, `{1}`, … – positional arguments (split by spaces)
|
| 168 |
+
- `{result}` – output of the previous step
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
|
| 170 |
+
Skills can also delegate to an external interpreter command (e.g., a Python script) via the optional `interpreter_command` field.
|
| 171 |
|
| 172 |
---
|
| 173 |
|
| 174 |
+
## Soul File
|
|
|
|
|
|
|
|
|
|
| 175 |
|
| 176 |
+
All persistent memories are written to `shadowclaw_data/shadowsoul.md` in Markdown format. It contains:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
|
| 178 |
+
- `## Core Memory` – JSON key‑value store.
|
| 179 |
+
- `## Skills` – list of registered skills (JSON).
|
| 180 |
+
- `## Cron Jobs` – all scheduled jobs.
|
| 181 |
+
- `## Webhooks` – registered webhooks.
|
| 182 |
+
- `## Conversation Log` – user, assistant, tool calls, and results.
|
| 183 |
|
| 184 |
+
The file is updated every 5 writes (write‑behind) and immediately after important events.
|
|
|
|
|
|
|
|
|
|
| 185 |
|
| 186 |
+
---
|
|
|
|
|
|
|
|
|
|
| 187 |
|
| 188 |
+
## ⚙️ Configuration via Environment Variables
|
|
|
|
|
|
|
|
|
|
| 189 |
|
| 190 |
+
| Variable | Default | Description |
|
| 191 |
+
|----------|---------|-------------|
|
| 192 |
+
| `SHADOWCLAW_CONNECT_TIMEOUT` | 10 | Seconds to wait for Ollama connection. |
|
| 193 |
+
| `SHADOWCLAW_TOTAL_TIMEOUT` | 120 | Total LLM request timeout (increased on retries). |
|
| 194 |
+
| `SHADOWCLAW_RETRY_ATTEMPTS` | 3 | Number of retries with exponential backoff. |
|
| 195 |
|
| 196 |
---
|
| 197 |
|
| 198 |
+
## 📁 Project Structure
|
| 199 |
|
| 200 |
+
```
|
| 201 |
+
shadowclaw/
|
| 202 |
+
├── shadowclaw.c # Main program, arena, tools, cron, LLM
|
| 203 |
+
├── interpreter.c # Local command interpreter (used in --no-llm mode)
|
| 204 |
+
├── interpreter.h # Header for interpreter
|
| 205 |
+
├── cJSON.c / cJSON.h # JSON library
|
| 206 |
+
├── Makefile # Build instructions
|
| 207 |
+
├── start.sh # Helper startup script (checks dependencies)
|
| 208 |
+
└── README.md # This file
|
| 209 |
+
```
|
| 210 |
|
| 211 |
+
## 📄 License
|
| 212 |
|
| 213 |
+
MIT License.
|
|
|