Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ Copy the template as-is to `daemon/loop.md`. **No placeholder replacement needed
{"sent":[],"pending":[],"failed":[],"follow_ups":[],"next_id":1,"budget":{"cycle_limit_sats":300,"daily_limit_sats":1500,"spent_today_sats":0,"last_reset":"","consecutive_failures":0,"outreach_paused_until":null}}
```

**`daemon/bridge-state.json`**:
```json
{"in_flight":false,"txid":null,"amount_sats":0,"started_at":null,"last_status":"idle"}
```

### `memory/` directory

**`memory/journal.md`**: `# Journal`
Expand Down Expand Up @@ -232,6 +237,49 @@ Show current state of the agent without entering the loop.

---

## Windows Compatibility

> **This kit requires a Unix-compatible shell.** All shell commands assume bash.
>
> - **Recommended on Windows:** Git Bash or WSL2. Native cmd.exe and PowerShell are not supported.
> - **Not recommended:** Running the loop in a native Windows terminal without Git Bash / WSL2.

If you are running on Windows + Git Bash (not WSL), be aware of these known issues and workarounds:

| Issue | Workaround |
|-------|------------|
| `curl -d @file` fails silently | Use `curl --data-binary @file` instead |
| `python3` not found (redirects to Microsoft Store) | Use `node -e` for JSON parsing (see below) |
| `spawn('npx', ...)` fails with ENOENT in Node.js scripts | Use `spawn('cmd', ['/c', 'npx', ...])` |
| `cp` path resolution fails if CWD is not the agent root | Always run commands from the agent root directory, or use absolute paths |

**JSON parsing without python3:**
```bash
# Instead of: python3 -c "import json,sys; print(json.load(sys.stdin)['key'])"
node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(d.key);"

# Or when reading a file directly:
node -e "const p=JSON.parse(require('fs').readFileSync('daemon/health.json','utf8')); console.log(p.cycle);"
```

**HTTP requests without python3:**
```bash
# Instead of: curl -d @file.json ...
curl --data-binary @file.json -H "Content-Type: application/json" ...
```

**Node.js child_process on Windows:**
```js
// Instead of: spawn('npx', ['--yes', '@aibtc/mcp-server@latest'])
spawn('cmd', ['/c', 'npx', '--yes', '@aibtc/mcp-server@latest'])
```

These workarounds apply to `daemon/loop.md` Phase 0 (MCP version check uses `python3`) and any shell
commands in the loop that parse JSON via python3. When editing `daemon/loop.md` for Windows, substitute
the `node -e` equivalents above.

---

## Setup Step 3: Verify AIBTC MCP server

The install script pre-configures `.mcp.json` so the MCP server loads automatically on first launch.
Expand Down Expand Up @@ -546,7 +594,7 @@ Heartbeat: OK

Files created:
CLAUDE.md, SOUL.md, .gitignore
daemon/loop.md, STATE.md, health.json, queue.json, processed.json, outbox.json
daemon/loop.md, STATE.md, health.json, queue.json, processed.json, outbox.json, bridge-state.json
memory/journal.md, contacts.md, learnings.md
.claude/skills/loop-stop/, .claude/skills/loop-status/

Expand Down
6 changes: 6 additions & 0 deletions daemon/loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ CACHED=$(python3 -c "import json; print(json.load(open('daemon/health.json')).ge
[ -z "$CACHED" ] && CACHED="unknown"
```

> **Windows/Git Bash note:** If `python3` is unavailable, substitute `node -e` equivalents:
> ```bash
> LATEST=$(curl -s https://api.github.com/repos/aibtcdev/aibtc-mcp-server/releases/latest | node -e "let d=''; process.stdin.on('data',c=>d+=c).on('end',()=>console.log((JSON.parse(d).tag_name||'').replace('mcp-server-v','')))" 2>/dev/null)
> CACHED=$(node -e "console.log(JSON.parse(require('fs').readFileSync('daemon/health.json','utf8')).mcp_version_cached||'unknown')" 2>/dev/null) || CACHED="unknown"
> ```

- **First run** (`CACHED` is "unknown"): set `mcp_version_cached` to `LATEST` in health.json. Continue normally.
- **Version match**: Set `mcp_update_required` to `false` in health.json (clears the flag after a restart). Continue normally.
- **Version mismatch** (`LATEST` != `CACHED`): set `mcp_update_required: true` **and** `mcp_version_cached` to `LATEST` in health.json. Complete the current cycle normally, then in Phase 9 (Sleep), exit instead of sleeping with message: "MCP update detected ({CACHED} -> {LATEST}). Exiting for restart. Run /loop-start to resume with updated version."
Expand Down