Goal: SmallClaw should be able to detect errors in its own background tasks, analyze their root cause in its own source code, propose a fix, wait for your explicit approval, apply the patch, rebuild, and report back — all over Telegram.
- SmallClaw is running a background task while you're away
- It hits an error — maybe a bug in a tool, a type mismatch, a broken import
- Instead of just dying silently, it captures the full error + stack trace
- You come back and say: "Hey Claw, what happened with that task? Can you figure out the fix?"
- SmallClaw reads its own source, analyzes the error, and replies: "Found it. Here's what broke and why. Want me to fix it?"
- You say: "Yes, go ahead"
- It applies a surgical patch, rebuilds, restarts, and messages you: "Done. Back online."
Or even more autonomously: it proactively messages you when it hits an error — "I hit a bug in task-runner.ts. I think I know how to fix it. Want me to analyze it properly and propose a patch?"
| Component | File | Status |
|---|---|---|
| Background task engine | src/gateway/task-runner.ts |
✅ Complete |
| Multi-step task loop | src/gateway/task-store.ts |
✅ Complete |
| Error capture in tasks | TaskState.error field |
✅ Complete |
| File read/write/edit tools | src/tools/files.ts |
✅ Complete |
apply_patch tool (unified diff) |
src/tools/files.ts |
✅ Complete |
| Self-update (git pull + rebuild + restart) | src/tools/self-update.ts |
✅ Complete |
| Telegram proactive messaging | telegram-channel.ts |
✅ Complete |
needs_approval job status |
src/types.ts |
✅ Complete |
| Personality / soul files | workspace/SOUL.md, IDENTITY.md |
✅ Complete |
The read / edit tools are path-locked to workspace/. The src/ directory is completely invisible to the AI. This is the single biggest blocker.
Fix: Add a read_source tool (read-only) that exposes src/ files to the AI. Separately, add a patch_source tool that applies a unified diff to src/ files — but this tool requires an approval_token to execute (generated by you saying "yes go ahead").
The AI has SOUL.md (who it is) and TOOLS.md (what tools it has) but nothing that tells it:
- Where the source files live
- What each file does
- How the build process works
- What the error log locations are
Fix: Create workspace/SELF.md — a map of SmallClaw's own architecture that gets injected into the system prompt like the other workspace files. The AI can then reason about where a bug would live given an error message.
Create workspace/SELF.md with:
- Full source tree map with one-line descriptions of each file
- Build process explanation (
npm run build→dist/) - Error log locations (
gateway.log,gateway.err.log) - How the task runner captures errors
- Where to look for stack traces
This costs nothing to implement — it's just a markdown file — but it dramatically improves the AI's ability to reason about errors.
Deliverable: workspace/SELF.md
A new tool that lets the AI read files from src/ (read-only, no writes).
// src/tools/source-access.ts
read_source({ path: 'gateway/telegram-channel.ts', start_line: 1, num_lines: 50 })
list_source({ path: 'gateway' }) // list files in a src/ subdirectorySecurity: Read-only. Path is always resolved relative to src/. No writes, no deletes, no traversal outside src/.
Deliverable: src/tools/source-access.ts, registered in registry.ts
Add a propose_repair tool. This tool:
- Takes an error message + optional stack trace
- Uses the AI's knowledge of the source (via
read_source) to identify the likely file and line - Generates a unified diff patch
- Stores the patch in a pending state (does NOT apply it yet)
- Formats a clear human-readable proposal and sends it to Telegram
- Waits for your
/approve <repair-id>or/reject <repair-id>command
The patch is stored as a JSON file in .smallclaw/pending-repairs/.
Pending repair #3:
━━━━━━━━━━━━━━━━━━━━━━━━
📍 File: src/tools/files.ts
❌ Error: Cannot read property 'path' of undefined (line 42)
🔍 Cause: args object not validated before destructuring
🩹 Fix: Add null-check guard before line 42
--- a/src/tools/files.ts
+++ b/src/tools/files.ts
@@ -40,6 +40,9 @@
export async function executeRead(args: ReadToolArgs) {
+ if (!args || typeof args.path !== 'string') {
+ return { success: false, error: 'path is required' };
+ }
const absPath = resolveWorkspacePath(args.path);
━━━━━━━━━━━━━━━━━━━━━━━━
Reply /approve 3 to apply, or /reject 3 to discard.
Deliverable: src/tools/self-repair.ts
When you reply /approve <id>:
- Load the pending repair from
.smallclaw/pending-repairs/<id>.json - Check the patch still applies cleanly (
git apply --check) - Apply it to
src/ - Run
npm run build - If build passes → restart gateway → message "Fixed and back online ✅"
- If build fails → revert the patch → message "Build failed after patch, reverted ❌. Here's the compiler error:"
The /reject <id> command just deletes the pending file and messages "Repair discarded."
Deliverable: Approval handling in telegram-channel.ts + src/tools/self-repair.ts
When a background task fails with an error that looks like a source code bug (stack trace points to src/ or dist/), SmallClaw automatically:
- Captures the error + stack
- Does a quick analysis (does the stack point to a known source file?)
- Messages you: "Task X failed with what looks like a source bug. Want me to analyze it?"
This makes the whole loop feel truly autonomous — it notices, it tells you, it waits for your go-ahead.
Background Task Running
│
▼
Error Occurs
│
├─── Stack trace captured in TaskState.error
│
▼
You: "Claw, analyze that error"
│
▼
AI reads SELF.md → knows which file to look at
│
▼
AI calls read_source() → reads the actual source file
│
▼
AI generates unified diff patch
│
▼
propose_repair() → stores patch, sends Telegram proposal
│
▼
You: "/approve 3"
│
▼
patch_source() → applies diff to src/
│
▼
npm run build
│
┌────┴────┐
│ │
PASS FAIL
│ │
Restart Revert + notify
│
Message: "Fixed ✅"
| Action | Allowed | Requires |
|---|---|---|
| Read source files | ✅ | AI can do autonomously |
| List source files | ✅ | AI can do autonomously |
| Analyze error + propose patch | ✅ | AI can do autonomously |
| Apply patch to source | 🔒 | Your explicit /approve <id> |
| Run build | 🔒 | Triggered only after your approval |
| Restart gateway | 🔒 | Triggered only after successful build |
| Modify workspace files | ✅ | Already permitted (existing tools) |
The AI cannot apply any source changes without an explicit approval command from you. Period.
-
workspace/SELF.md— architecture map for the AI -
src/tools/source-access.ts—read_sourceandlist_sourcetools -
src/tools/self-repair.ts—propose_repairtool + patch storage -
src/gateway/telegram-channel.ts—/approveand/rejectcommand handlers -
src/tools/registry.ts— register the two new tools -
CHANGELOG.md— document the feature when shipped
-
Model capability: Self-repair requires the AI to write valid unified diffs. Qwen3:4b may struggle with this — consider gating
propose_repairbehind the secondary/orchestration model if one is configured. -
Build output: Should build errors be sent in full to Telegram (could be long) or truncated? Suggest: first 50 lines of compiler output, with a
/browselink to the full log. -
Repair history: Should accepted/rejected repairs be logged to
workspace/memory/? Recommended yes — gives the AI long-term awareness of what bugs it has found and fixed. -
Auto-propose threshold: Should the AI proactively propose repairs without being asked, or only when you explicitly ask? Recommend: proactive notification ("I found a bug") but passive proposal ("want me to analyze it?") — never auto-apply.