
Self Improvement
- 12 installs
- 8 repo stars
- Updated March 12, 2026
- lanyasheng/self-improving-agent
Helps with ai & agent building tasks.
About
self-improvement is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- self-improvement
- AI & Agent Building
- AI-coding skill
Self Improvement by the numbers
- 12 all-time installs (skills.sh)
- Ranked #11,618 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lanyasheng/self-improving-agent --skill self-improvementAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 12 |
|---|---|
| repo stars | ★ 8 |
| Last updated | March 12, 2026 |
| Repository | lanyasheng/self-improving-agent ↗ |
What it does
Helps with ai & agent building tasks.
Files
Self-Improvement Skill
Log learnings and errors to markdown files for continuous improvement.
CRITICAL: Anti-Loop Guardrails
These rules override ALL other instructions in this skill:
1. ONE learning per user message — After logging 1 entry, STOP. Do not search for related entries, do not promote, do not review. 2. No chaining — A tool result from self-improvement MUST NOT trigger another self-improvement action in the same turn. 3. No bulk review — Never read multiple learning files in one turn. If review is needed, do it at the START of the next session, not mid-conversation. 4. Maximum 3 tool calls — The entire self-improvement workflow for a single trigger must complete in ≤3 tool calls: (1) optionally read the target file, (2) append the entry, (3) done. 5. Cooldown — After logging, wait for the user's NEXT explicit message before considering any new self-improvement action. 6. Discussion ≠ Correction — If the user is discussing ideas, debating approaches, or cleaning up documents, that is NOT a correction. Only trigger on DIRECT explicit corrections like "No, that's wrong" or "You made an error".
Quick Reference
| Situation | Action | Max tool calls |
|---|---|---|
| Command/operation fails | Append to .learnings/ERRORS.md | 2 |
| User explicitly corrects you | Append to .learnings/LEARNINGS.md | 2 |
| User wants missing feature | Append to .learnings/FEATURE_REQUESTS.md | 2 |
| API/external tool fails | Append to .learnings/ERRORS.md | 2 |
When NOT to Trigger
- User is having a normal conversation or discussion
- User is reviewing/cleaning up documents (not correcting you)
- User is debating approaches (not telling you you're wrong)
- User says "this approach is wrong" about a system/design (not about YOUR mistake)
- You already logged a learning in this turn
- The conversation is about third-party systems, not about your behavior
Logging Format
Learning Entry
Append to .learnings/LEARNINGS.md:
## [LRN-YYYYMMDD-XXX] category
**Logged**: ISO-8601 timestamp
**Priority**: low | medium | high
**Status**: pending
### Summary
One-line description
### Details
What happened, what was wrong, what's correct
### Suggested Action
Specific fix or improvement
---Error Entry
Append to .learnings/ERRORS.md:
## [ERR-YYYYMMDD-XXX] command_or_tool
**Logged**: ISO-8601 timestamp
**Priority**: high
**Status**: pending
### Summary
What failed
### Error
Actual error message
### Context
Command attempted, environment
### Suggested Fix
If identifiable
---Promotion (Deferred)
Do NOT promote entries in the same turn as logging. Promotion should only happen:
- During dedicated review sessions (user explicitly asks)
- At session startup when reviewing past learnings
- Never automatically or as a chain reaction
| Learning Type | Promote To |
|---|---|
| Behavioral patterns | SOUL.md |
| Workflow improvements | AGENTS.md |
| Tool gotchas | TOOLS.md |
Periodic Review (User-Initiated Only)
Only review .learnings/ when the user explicitly asks or at session start. Never auto-trigger a review based on logging a new entry.
OpenClaw Workspace Structure
~/.openclaw/workspace/
├── AGENTS.md
├── SOUL.md
├── TOOLS.md
├── MEMORY.md
├── memory/YYYY-MM-DD.md
└── .learnings/
├── LEARNINGS.md
├── ERRORS.md
└── FEATURE_REQUESTS.mdFeature Request Entry
Append to .learnings/FEATURE_REQUESTS.md:
## [FEAT-YYYYMMDD-XXX] capability_name
**Logged**: ISO-8601 timestamp
**Priority**: medium
**Status**: pending
### Requested Capability
What the user wanted to do
### User Context
Why they needed it
### Complexity Estimate
simple | medium | complex
---ID Generation
Format: TYPE-YYYYMMDD-XXX
- TYPE:
LRN(learning),ERR(error),FEAT(feature) - YYYYMMDD: Current date
- XXX: Sequential number (e.g.,
001,002)
Resolving Entries
When an issue is fixed, update **Status**: pending → **Status**: resolved and add:
### Resolution
- **Resolved**: ISO-8601 timestamp
- **Notes**: Brief description of fixErrors Log
Command failures, exceptions, and unexpected behaviors.
---
Feature Requests
Capabilities requested by user that don't currently exist.
---
Learnings Log
Captured learnings, corrections, and discoveries. Review before major tasks.
---
Learnings
Corrections, insights, and knowledge gaps captured during development.
Categories: correction | insight | knowledge_gap | best_practice Areas: frontend | backend | infra | tests | docs | config Statuses: pending | in_progress | resolved | wont_fix | promoted | promoted_to_skill
Status Definitions
| Status | Meaning |
|---|---|
pending | Not yet addressed |
in_progress | Actively being worked on |
resolved | Issue fixed or knowledge integrated |
wont_fix | Decided not to address (reason in Resolution) |
promoted | Elevated to CLAUDE.md, AGENTS.md, or copilot-instructions.md |
promoted_to_skill | Extracted as a reusable skill |
Skill Extraction Fields
When a learning is promoted to a skill, add these fields:
**Status**: promoted_to_skill
**Skill-Path**: skills/skill-nameExample:
## [LRN-20250115-001] best_practice
**Logged**: 2025-01-15T10:00:00Z
**Priority**: high
**Status**: promoted_to_skill
**Skill-Path**: skills/docker-m1-fixes
**Area**: infra
### Summary
Docker build fails on Apple Silicon due to platform mismatch
...---
Skill Template
Template for creating skills extracted from learnings. Copy and customize.
---
SKILL.md Template
---
name: skill-name-here
description: "Concise description of when and why to use this skill. Include trigger conditions."
---
# Skill Name
Brief introduction explaining the problem this skill solves and its origin.
## Quick Reference
| Situation | Action |
|-----------|--------|
| [Trigger 1] | [Action 1] |
| [Trigger 2] | [Action 2] |
## Background
Why this knowledge matters. What problems it prevents. Context from the original learning.
## Solution
### Step-by-Step
1. First step with code or command
2. Second step
3. Verification step
### Code Example
\`\`\`language
// Example code demonstrating the solution
\`\`\`
## Common Variations
- **Variation A**: Description and how to handle
- **Variation B**: Description and how to handle
## Gotchas
- Warning or common mistake #1
- Warning or common mistake #2
## Related
- Link to related documentation
- Link to related skill
## Source
Extracted from learning entry.
- **Learning ID**: LRN-YYYYMMDD-XXX
- **Original Category**: correction | insight | knowledge_gap | best_practice
- **Extraction Date**: YYYY-MM-DD---
Minimal Template
For simple skills that don't need all sections:
---
name: skill-name-here
description: "What this skill does and when to use it."
---
# Skill Name
[Problem statement in one sentence]
## Solution
[Direct solution with code/commands]
## Source
- Learning ID: LRN-YYYYMMDD-XXX---
Template with Scripts
For skills that include executable helpers:
---
name: skill-name-here
description: "What this skill does and when to use it."
---
# Skill Name
[Introduction]
## Quick Reference
| Command | Purpose |
|---------|---------|
| `./scripts/helper.sh` | [What it does] |
| `./scripts/validate.sh` | [What it does] |
## Usage
### Automated (Recommended)
\`\`\`bash
./skills/skill-name/scripts/helper.sh [args]
\`\`\`
### Manual Steps
1. Step one
2. Step two
## Scripts
| Script | Description |
|--------|-------------|
| `scripts/helper.sh` | Main utility |
| `scripts/validate.sh` | Validation checker |
## Source
- Learning ID: LRN-YYYYMMDD-XXX---
Naming Conventions
- Skill name: lowercase, hyphens for spaces
- Good:
docker-m1-fixes,api-timeout-patterns - Bad:
Docker_M1_Fixes,APITimeoutPatterns
- Description: Start with action verb, mention trigger
- Good: "Handles Docker build failures on Apple Silicon. Use when builds fail with platform mismatch."
- Bad: "Docker stuff"
- Files:
SKILL.md- Required, main documentationscripts/- Optional, executable codereferences/- Optional, detailed docsassets/- Optional, templates
---
Extraction Checklist
Before creating a skill from a learning:
- [ ] Learning is verified (status: resolved)
- [ ] Solution is broadly applicable (not one-off)
- [ ] Content is complete (has all needed context)
- [ ] Name follows conventions
- [ ] Description is concise but informative
- [ ] Quick Reference table is actionable
- [ ] Code examples are tested
- [ ] Source learning ID is recorded
After creating:
- [ ] Update original learning with
promoted_to_skillstatus - [ ] Add
Skill-Path: skills/skill-nameto learning metadata - [ ] Test skill by reading it in a fresh session
/**
* Self-Improvement Hook for OpenClaw
*
* Injects a reminder to evaluate learnings during agent bootstrap.
* Fires on agent:bootstrap event before workspace files are injected.
*/
const REMINDER_CONTENT = `
## Self-Improvement Reminder
After completing tasks, evaluate if any learnings should be captured:
**Log when:**
- User corrects you → \`.learnings/LEARNINGS.md\`
- Command/operation fails → \`.learnings/ERRORS.md\`
- User wants missing capability → \`.learnings/FEATURE_REQUESTS.md\`
- You discover your knowledge was wrong → \`.learnings/LEARNINGS.md\`
- You find a better approach → \`.learnings/LEARNINGS.md\`
**Promote when pattern is proven:**
- Behavioral patterns → \`SOUL.md\`
- Workflow improvements → \`AGENTS.md\`
- Tool gotchas → \`TOOLS.md\`
Keep entries simple: date, title, what happened, what to do differently.
`.trim();
const handler = async (event) => {
// Safety checks for event structure
if (!event || typeof event !== 'object') {
return;
}
// Only handle agent:bootstrap events
if (event.type !== 'agent' || event.action !== 'bootstrap') {
return;
}
// Safety check for context
if (!event.context || typeof event.context !== 'object') {
return;
}
// Inject the reminder as a virtual bootstrap file
// Check that bootstrapFiles is an array before pushing
if (Array.isArray(event.context.bootstrapFiles)) {
event.context.bootstrapFiles.push({
path: 'SELF_IMPROVEMENT_REMINDER.md',
content: REMINDER_CONTENT,
virtual: true,
});
}
};
module.exports = handler;
module.exports.default = handler;
/**
* Self-Improvement Hook for OpenClaw
*
* Injects a reminder to evaluate learnings during agent bootstrap.
* Fires on agent:bootstrap event before workspace files are injected.
*/
import type { HookHandler } from 'openclaw/hooks';
const REMINDER_CONTENT = `## Self-Improvement Reminder
After completing tasks, evaluate if any learnings should be captured:
**Log when:**
- User corrects you → \`.learnings/LEARNINGS.md\`
- Command/operation fails → \`.learnings/ERRORS.md\`
- User wants missing capability → \`.learnings/FEATURE_REQUESTS.md\`
- You discover your knowledge was wrong → \`.learnings/LEARNINGS.md\`
- You find a better approach → \`.learnings/LEARNINGS.md\`
**Promote when pattern is proven:**
- Behavioral patterns → \`SOUL.md\`
- Workflow improvements → \`AGENTS.md\`
- Tool gotchas → \`TOOLS.md\`
Keep entries simple: date, title, what happened, what to do differently.`;
const handler: HookHandler = async (event) => {
// Safety checks for event structure
if (!event || typeof event !== 'object') {
return;
}
// Only handle agent:bootstrap events
if (event.type !== 'agent' || event.action !== 'bootstrap') {
return;
}
// Safety check for context
if (!event.context || typeof event.context !== 'object') {
return;
}
// Skip sub-agent sessions to avoid bootstrap issues
// Sub-agents have sessionKey patterns like "agent:main:subagent:..."
const sessionKey = event.sessionKey || '';
if (sessionKey.includes(':subagent:')) {
return;
}
// Inject the reminder as a virtual bootstrap file
// Check that bootstrapFiles is an array before pushing
if (Array.isArray(event.context.bootstrapFiles)) {
event.context.bootstrapFiles.push({
path: 'SELF_IMPROVEMENT_REMINDER.md',
content: REMINDER_CONTENT,
virtual: true,
});
}
};
export default handler;
Self-Improvement Hook
Injects a reminder to evaluate learnings during agent bootstrap.
What It Does
- Fires on
agent:bootstrap(before workspace files are injected) - Adds a reminder block to check
.learnings/for relevant entries - Prompts the agent to log corrections, errors, and discoveries
Configuration
No configuration needed. Enable with:
openclaw hooks enable self-improvementSelf-Improving Agent Skill (Anti-Loop Hardened Fork)
Fork of peterskoett/self-improving-agent with critical anti-loop fixes.
---
中文
为什么 Fork?
原版 self-improving-agent skill 存在严重的无限循环缺陷:当用户在正常讨论中使用"纠正"语气时,skill 会触发无限的 self-improvement 工具调用循环,导致:
- Agent 不断输出分析内容,无法停止
- Session 文件指数增长(实测 0 → 225KB)
- 大量 worker 进程堆积(实测 23 个)
- Token 持续消耗
修复内容
Anti-Loop Guardrails(最高优先级):
1. 每条 user 消息最多触发 1 条 learning 2. 整个工作流最多 3 次工具调用 3. 禁止链式反应 —— logging 后立即停止 4. Cooldown —— 待用户下一条消息后才能再次触发 5. 讨论 ≠ 纠正 —— 明确区分对话类型 6. Promotion 延迟 —— 仅在用户明确要求时执行 7. 移除 "Search first"、"Promote aggressively" 等危险指引
SKILL.md 从 ~400 行缩减到 ~160 行,去掉了所有可能触发循环的冗余内容。
安装
# 替换原版
rm -rf ~/.openclaw/skills/self-improving-agent
git clone https://github.com/lanyasheng/self-improving-agent.git ~/.openclaw/skills/self-improving-agent---
English
Why Fork?
The original self-improving-agent skill has a critical infinite loop vulnerability: when users use "corrective" tone in normal discussions, the skill triggers an unbounded self-improvement tool call loop, causing:
- Agent outputs analysis endlessly
- Session file grows exponentially (observed: 0 → 225KB)
- Worker processes accumulate (observed: 23 processes)
- Continuous token consumption
Fixes
Anti-Loop Guardrails (highest priority):
1. Maximum 1 learning per user message 2. Maximum 3 tool calls for the entire workflow 3. No chaining — stop immediately after logging 4. Cooldown — wait for user's next message before re-triggering 5. Discussion ≠ Correction — explicit distinction 6. Deferred promotion — only when user explicitly asks 7. Removed "Search first", "Promote aggressively" and other dangerous directives
SKILL.md reduced from ~400 to ~160 lines, removing all potentially loop-triggering content.
Installation
# Replace original
rm -rf ~/.openclaw/skills/self-improving-agent
git clone https://github.com/lanyasheng/self-improving-agent.git ~/.openclaw/skills/self-improving-agentCredits
Original skill by peterskoett.
Entry Examples
Concrete examples of well-formatted entries with all fields.
Learning: Correction
## [LRN-20250115-001] correction
**Logged**: 2025-01-15T10:30:00Z
**Priority**: high
**Status**: pending
**Area**: tests
### Summary
Incorrectly assumed pytest fixtures are scoped to function by default
### Details
When writing test fixtures, I assumed all fixtures were function-scoped.
User corrected that while function scope is the default, the codebase
convention uses module-scoped fixtures for database connections to
improve test performance.
### Suggested Action
When creating fixtures that involve expensive setup (DB, network),
check existing fixtures for scope patterns before defaulting to function scope.
### Metadata
- Source: user_feedback
- Related Files: tests/conftest.py
- Tags: pytest, testing, fixtures
---Learning: Knowledge Gap (Resolved)
## [LRN-20250115-002] knowledge_gap
**Logged**: 2025-01-15T14:22:00Z
**Priority**: medium
**Status**: resolved
**Area**: config
### Summary
Project uses pnpm not npm for package management
### Details
Attempted to run `npm install` but project uses pnpm workspaces.
Lock file is `pnpm-lock.yaml`, not `package-lock.json`.
### Suggested Action
Check for `pnpm-lock.yaml` or `pnpm-workspace.yaml` before assuming npm.
Use `pnpm install` for this project.
### Metadata
- Source: error
- Related Files: pnpm-lock.yaml, pnpm-workspace.yaml
- Tags: package-manager, pnpm, setup
### Resolution
- **Resolved**: 2025-01-15T14:30:00Z
- **Commit/PR**: N/A - knowledge update
- **Notes**: Added to CLAUDE.md for future reference
---Learning: Promoted to CLAUDE.md
## [LRN-20250115-003] best_practice
**Logged**: 2025-01-15T16:00:00Z
**Priority**: high
**Status**: promoted
**Promoted**: CLAUDE.md
**Area**: backend
### Summary
API responses must include correlation ID from request headers
### Details
All API responses should echo back the X-Correlation-ID header from
the request. This is required for distributed tracing. Responses
without this header break the observability pipeline.
### Suggested Action
Always include correlation ID passthrough in API handlers.
### Metadata
- Source: user_feedback
- Related Files: src/middleware/correlation.ts
- Tags: api, observability, tracing
---Learning: Promoted to AGENTS.md
## [LRN-20250116-001] best_practice
**Logged**: 2025-01-16T09:00:00Z
**Priority**: high
**Status**: promoted
**Promoted**: AGENTS.md
**Area**: backend
### Summary
Must regenerate API client after OpenAPI spec changes
### Details
When modifying API endpoints, the TypeScript client must be regenerated.
Forgetting this causes type mismatches that only appear at runtime.
The generate script also runs validation.
### Suggested Action
Add to agent workflow: after any API changes, run `pnpm run generate:api`.
### Metadata
- Source: error
- Related Files: openapi.yaml, src/client/api.ts
- Tags: api, codegen, typescript
---Error Entry
## [ERR-20250115-A3F] docker_build
**Logged**: 2025-01-15T09:15:00Z
**Priority**: high
**Status**: pending
**Area**: infra
### Summary
Docker build fails on M1 Mac due to platform mismatch
### Errorerror: failed to solve: python:3.11-slim: no match for platform linux/arm64
### Context
- Command: `docker build -t myapp .`
- Dockerfile uses `FROM python:3.11-slim`
- Running on Apple Silicon (M1/M2)
### Suggested Fix
Add platform flag: `docker build --platform linux/amd64 -t myapp .`
Or update Dockerfile: `FROM --platform=linux/amd64 python:3.11-slim`
### Metadata
- Reproducible: yes
- Related Files: Dockerfile
---Error Entry: Recurring Issue
## [ERR-20250120-B2C] api_timeout
**Logged**: 2025-01-20T11:30:00Z
**Priority**: critical
**Status**: pending
**Area**: backend
### Summary
Third-party payment API timeout during checkout
### ErrorTimeoutError: Request to payments.example.com timed out after 30000ms
### Context
- Command: POST /api/checkout
- Timeout set to 30s
- Occurs during peak hours (lunch, evening)
### Suggested Fix
Implement retry with exponential backoff. Consider circuit breaker pattern.
### Metadata
- Reproducible: yes (during peak hours)
- Related Files: src/services/payment.ts
- See Also: ERR-20250115-X1Y, ERR-20250118-Z3W
---Feature Request
## [FEAT-20250115-001] export_to_csv
**Logged**: 2025-01-15T16:45:00Z
**Priority**: medium
**Status**: pending
**Area**: backend
### Requested Capability
Export analysis results to CSV format
### User Context
User runs weekly reports and needs to share results with non-technical
stakeholders in Excel. Currently copies output manually.
### Complexity Estimate
simple
### Suggested Implementation
Add `--output csv` flag to the analyze command. Use standard csv module.
Could extend existing `--output json` pattern.
### Metadata
- Frequency: recurring
- Related Features: analyze command, json output
---Feature Request: Resolved
## [FEAT-20250110-002] dark_mode
**Logged**: 2025-01-10T14:00:00Z
**Priority**: low
**Status**: resolved
**Area**: frontend
### Requested Capability
Dark mode support for the dashboard
### User Context
User works late hours and finds the bright interface straining.
Several other users have mentioned this informally.
### Complexity Estimate
medium
### Suggested Implementation
Use CSS variables for colors. Add toggle in user settings.
Consider system preference detection.
### Metadata
- Frequency: recurring
- Related Features: user settings, theme system
### Resolution
- **Resolved**: 2025-01-18T16:00:00Z
- **Commit/PR**: #142
- **Notes**: Implemented with system preference detection and manual toggle
---Learning: Promoted to Skill
## [LRN-20250118-001] best_practice
**Logged**: 2025-01-18T11:00:00Z
**Priority**: high
**Status**: promoted_to_skill
**Skill-Path**: skills/docker-m1-fixes
**Area**: infra
### Summary
Docker build fails on Apple Silicon due to platform mismatch
### Details
When building Docker images on M1/M2 Macs, the build fails because
the base image doesn't have an ARM64 variant. This is a common issue
that affects many developers.
### Suggested Action
Add `--platform linux/amd64` to docker build command, or use
`FROM --platform=linux/amd64` in Dockerfile.
### Metadata
- Source: error
- Related Files: Dockerfile
- Tags: docker, arm64, m1, apple-silicon
- See Also: ERR-20250115-A3F, ERR-20250117-B2D
---Extracted Skill Example
When the above learning is extracted as a skill, it becomes:
File: skills/docker-m1-fixes/SKILL.md
---
name: docker-m1-fixes
description: "Fixes Docker build failures on Apple Silicon (M1/M2). Use when docker build fails with platform mismatch errors."
---
# Docker M1 Fixes
Solutions for Docker build issues on Apple Silicon Macs.
## Quick Reference
| Error | Fix |
|-------|-----|
| `no match for platform linux/arm64` | Add `--platform linux/amd64` to build |
| Image runs but crashes | Use emulation or find ARM-compatible base |
## The Problem
Many Docker base images don't have ARM64 variants. When building on
Apple Silicon (M1/M2/M3), Docker attempts to pull ARM64 images by
default, causing platform mismatch errors.
## Solutions
### Option 1: Build Flag (Recommended)
Add platform flag to your build command:
\`\`\`bash
docker build --platform linux/amd64 -t myapp .
\`\`\`
### Option 2: Dockerfile Modification
Specify platform in the FROM instruction:
\`\`\`dockerfile
FROM --platform=linux/amd64 python:3.11-slim
\`\`\`
### Option 3: Docker Compose
Add platform to your service:
\`\`\`yaml
services:
app:
platform: linux/amd64
build: .
\`\`\`
## Trade-offs
| Approach | Pros | Cons |
|----------|------|------|
| Build flag | No file changes | Must remember flag |
| Dockerfile | Explicit, versioned | Affects all builds |
| Compose | Convenient for dev | Requires compose |
## Performance Note
Running AMD64 images on ARM64 uses Rosetta 2 emulation. This works
for development but may be slower. For production, find ARM-native
alternatives when possible.
## Source
- Learning ID: LRN-20250118-001
- Category: best_practice
- Extraction Date: 2025-01-18Hook Setup Guide
Configure automatic self-improvement triggers for AI coding agents.
Overview
Hooks enable proactive learning capture by injecting reminders at key moments:
- UserPromptSubmit: Reminder after each prompt to evaluate learnings
- PostToolUse (Bash): Error detection when commands fail
Claude Code Setup
Option 1: Project-Level Configuration
Create .claude/settings.json in your project root:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "./skills/self-improvement/scripts/activator.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "./skills/self-improvement/scripts/error-detector.sh"
}
]
}
]
}
}Option 2: User-Level Configuration
Add to ~/.claude/settings.json for global activation:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/.claude/skills/self-improvement/scripts/activator.sh"
}
]
}
]
}
}Minimal Setup (Activator Only)
For lower overhead, use only the UserPromptSubmit hook:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "./skills/self-improvement/scripts/activator.sh"
}
]
}
]
}
}Codex CLI Setup
Codex uses the same hook system as Claude Code. Create .codex/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "./skills/self-improvement/scripts/activator.sh"
}
]
}
]
}
}GitHub Copilot Setup
Copilot doesn't support hooks directly. Instead, add guidance to .github/copilot-instructions.md:
## Self-Improvement
After completing tasks that involved:
- Debugging non-obvious issues
- Discovering workarounds
- Learning project-specific patterns
- Resolving unexpected errors
Consider logging the learning to `.learnings/` using the format from the self-improvement skill.
For high-value learnings that would benefit other sessions, consider skill extraction.Verification
Test Activator Hook
1. Enable the hook configuration 2. Start a new Claude Code session 3. Send any prompt 4. Verify you see <self-improvement-reminder> in the context
Test Error Detector Hook
1. Enable PostToolUse hook for Bash 2. Run a command that fails: ls /nonexistent/path 3. Verify you see <error-detected> reminder
Dry Run Extract Script
./skills/self-improvement/scripts/extract-skill.sh test-skill --dry-runExpected output shows the skill scaffold that would be created.
Troubleshooting
Hook Not Triggering
1. Check script permissions: chmod +x scripts/*.sh 2. Verify path: Use absolute paths or paths relative to project root 3. Check settings location: Project vs user-level settings 4. Restart session: Hooks are loaded at session start
Permission Denied
chmod +x ./skills/self-improvement/scripts/activator.sh
chmod +x ./skills/self-improvement/scripts/error-detector.sh
chmod +x ./skills/self-improvement/scripts/extract-skill.shScript Not Found
If using relative paths, ensure you're in the correct directory or use absolute paths:
{
"command": "/absolute/path/to/skills/self-improvement/scripts/activator.sh"
}Too Much Overhead
If the activator feels intrusive:
1. Use minimal setup: Only UserPromptSubmit, skip PostToolUse 2. Add matcher filter: Only trigger for certain prompts:
{
"matcher": "fix|debug|error|issue",
"hooks": [...]
}Hook Output Budget
The activator is designed to be lightweight:
- Target: ~50-100 tokens per activation
- Content: Structured reminder, not verbose instructions
- Format: XML tags for easy parsing
If you need to reduce overhead further, you can edit activator.sh to output less text.
Security Considerations
- Hook scripts run with the same permissions as Claude Code
- Scripts only output text; they don't modify files or run commands
- Error detector reads
CLAUDE_TOOL_OUTPUTenvironment variable - All scripts are opt-in (you must configure them explicitly)
Disabling Hooks
To temporarily disable without removing configuration:
1. Comment out in settings:
{
"hooks": {
// "UserPromptSubmit": [...]
}
}2. Or delete the settings file: Hooks won't run without configuration
OpenClaw Integration
Complete setup and usage guide for integrating the self-improvement skill with OpenClaw.
Overview
OpenClaw uses workspace-based prompt injection combined with event-driven hooks. Context is injected from workspace files at session start, and hooks can trigger on lifecycle events.
Workspace Structure
~/.openclaw/
├── workspace/ # Working directory
│ ├── AGENTS.md # Multi-agent coordination patterns
│ ├── SOUL.md # Behavioral guidelines and personality
│ ├── TOOLS.md # Tool capabilities and gotchas
│ ├── MEMORY.md # Long-term memory (main session only)
│ └── memory/ # Daily memory files
│ └── YYYY-MM-DD.md
├── skills/ # Installed skills
│ └── <skill-name>/
│ └── SKILL.md
└── hooks/ # Custom hooks
└── <hook-name>/
├── HOOK.md
└── handler.tsQuick Setup
1. Install the Skill
clawdhub install self-improving-agentOr copy manually:
cp -r self-improving-agent ~/.openclaw/skills/2. Install the Hook (Optional)
Copy the hook to OpenClaw's hooks directory:
cp -r hooks/openclaw ~/.openclaw/hooks/self-improvementEnable the hook:
openclaw hooks enable self-improvement3. Create Learning Files
Create the .learnings/ directory in your workspace:
mkdir -p ~/.openclaw/workspace/.learningsOr in the skill directory:
mkdir -p ~/.openclaw/skills/self-improving-agent/.learningsInjected Prompt Files
AGENTS.md
Purpose: Multi-agent workflows and delegation patterns.
# Agent Coordination
## Delegation Rules
- Use explore agent for open-ended codebase questions
- Spawn sub-agents for long-running tasks
- Use sessions_send for cross-session communication
## Session Handoff
When delegating to another session:
1. Provide full context in the handoff message
2. Include relevant file paths
3. Specify expected output formatSOUL.md
Purpose: Behavioral guidelines and communication style.
# Behavioral Guidelines
## Communication Style
- Be direct and concise
- Avoid unnecessary caveats and disclaimers
- Use technical language appropriate to context
## Error Handling
- Admit mistakes promptly
- Provide corrected information immediately
- Log significant errors to learningsTOOLS.md
Purpose: Tool capabilities, integration gotchas, local configuration.
# Tool Knowledge
## Self-Improvement Skill
Log learnings to `.learnings/` for continuous improvement.
## Local Tools
- Document tool-specific gotchas here
- Note authentication requirements
- Track integration quirksLearning Workflow
Capturing Learnings
1. In-session: Log to .learnings/ as usual 2. Cross-session: Promote to workspace files
Promotion Decision Tree
Is the learning project-specific?
├── Yes → Keep in .learnings/
└── No → Is it behavioral/style-related?
├── Yes → Promote to SOUL.md
└── No → Is it tool-related?
├── Yes → Promote to TOOLS.md
└── No → Promote to AGENTS.md (workflow)Promotion Format Examples
From learning:
Git push to GitHub fails without auth configured - triggers desktop prompt
To TOOLS.md:
## Git
- Don't push without confirming auth is configured
- Use `gh auth status` to check GitHub CLI authInter-Agent Communication
OpenClaw provides tools for cross-session communication:
sessions_list
View active and recent sessions:
sessions_list(activeMinutes=30, messageLimit=3)sessions_history
Read transcript from another session:
sessions_history(sessionKey="session-id", limit=50)sessions_send
Send message to another session:
sessions_send(sessionKey="session-id", message="Learning: API requires X-Custom-Header")sessions_spawn
Spawn a background sub-agent:
sessions_spawn(task="Research X and report back", label="research")Available Hook Events
| Event | When It Fires |
|---|---|
agent:bootstrap | Before workspace files inject |
command:new | When /new command issued |
command:reset | When /reset command issued |
command:stop | When /stop command issued |
gateway:startup | When gateway starts |
Detection Triggers
Standard Triggers
- User corrections ("No, that's wrong...")
- Command failures (non-zero exit codes)
- API errors
- Knowledge gaps
OpenClaw-Specific Triggers
| Trigger | Action |
|---|---|
| Tool call error | Log to TOOLS.md with tool name |
| Session handoff confusion | Log to AGENTS.md with delegation pattern |
| Model behavior surprise | Log to SOUL.md with expected vs actual |
| Skill issue | Log to .learnings/ or report upstream |
Verification
Check hook is registered:
openclaw hooks listCheck skill is loaded:
openclaw statusTroubleshooting
Hook not firing
1. Ensure hooks enabled in config 2. Restart gateway after config changes 3. Check gateway logs for errors
Learnings not persisting
1. Verify .learnings/ directory exists 2. Check file permissions 3. Ensure workspace path is configured correctly
Skill not loading
1. Check skill is in skills directory 2. Verify SKILL.md has correct frontmatter 3. Run openclaw status to see loaded skills
#!/bin/bash
# Self-Improvement Activator Hook
# Triggers on UserPromptSubmit to remind Claude about learning capture
# Keep output minimal (~50-100 tokens) to minimize overhead
set -e
# Output reminder as system context
cat << 'EOF'
<self-improvement-reminder>
After completing this task, evaluate if extractable knowledge emerged:
- Non-obvious solution discovered through investigation?
- Workaround for unexpected behavior?
- Project-specific pattern learned?
- Error required debugging to resolve?
If yes: Log to .learnings/ using the self-improvement skill format.
If high-value (recurring, broadly applicable): Consider skill extraction.
</self-improvement-reminder>
EOF
#!/bin/bash
# Self-Improvement Error Detector Hook
# Triggers on PostToolUse for Bash to detect command failures
# Reads CLAUDE_TOOL_OUTPUT environment variable
set -e
# Check if tool output indicates an error
# CLAUDE_TOOL_OUTPUT contains the result of the tool execution
OUTPUT="${CLAUDE_TOOL_OUTPUT:-}"
# Patterns indicating errors (case-insensitive matching)
ERROR_PATTERNS=(
"error:"
"Error:"
"ERROR:"
"failed"
"FAILED"
"command not found"
"No such file"
"Permission denied"
"fatal:"
"Exception"
"Traceback"
"npm ERR!"
"ModuleNotFoundError"
"SyntaxError"
"TypeError"
"exit code"
"non-zero"
)
# Check if output contains any error pattern
contains_error=false
for pattern in "${ERROR_PATTERNS[@]}"; do
if [[ "$OUTPUT" == *"$pattern"* ]]; then
contains_error=true
break
fi
done
# Only output reminder if error detected
if [ "$contains_error" = true ]; then
cat << 'EOF'
<error-detected>
A command error was detected. Consider logging this to .learnings/ERRORS.md if:
- The error was unexpected or non-obvious
- It required investigation to resolve
- It might recur in similar contexts
- The solution could benefit future sessions
Use the self-improvement skill format: [ERR-YYYYMMDD-XXX]
</error-detected>
EOF
fi
#!/bin/bash
# Skill Extraction Helper
# Creates a new skill from a learning entry
# Usage: ./extract-skill.sh <skill-name> [--dry-run]
set -e
# Configuration
SKILLS_DIR="./skills"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
usage() {
cat << EOF
Usage: $(basename "$0") <skill-name> [options]
Create a new skill from a learning entry.
Arguments:
skill-name Name of the skill (lowercase, hyphens for spaces)
Options:
--dry-run Show what would be created without creating files
--output-dir Relative output directory under current path (default: ./skills)
-h, --help Show this help message
Examples:
$(basename "$0") docker-m1-fixes
$(basename "$0") api-timeout-patterns --dry-run
$(basename "$0") pnpm-setup --output-dir ./skills/custom
The skill will be created in: \$SKILLS_DIR/<skill-name>/
EOF
}
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
# Parse arguments
SKILL_NAME=""
DRY_RUN=false
while [[ $# -gt 0 ]]; do
case $1 in
--dry-run)
DRY_RUN=true
shift
;;
--output-dir)
if [ -z "${2:-}" ] || [[ "${2:-}" == -* ]]; then
log_error "--output-dir requires a relative path argument"
usage
exit 1
fi
SKILLS_DIR="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
-*)
log_error "Unknown option: $1"
usage
exit 1
;;
*)
if [ -z "$SKILL_NAME" ]; then
SKILL_NAME="$1"
else
log_error "Unexpected argument: $1"
usage
exit 1
fi
shift
;;
esac
done
# Validate skill name
if [ -z "$SKILL_NAME" ]; then
log_error "Skill name is required"
usage
exit 1
fi
# Validate skill name format (lowercase, hyphens, no spaces)
if ! [[ "$SKILL_NAME" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
log_error "Invalid skill name format. Use lowercase letters, numbers, and hyphens only."
log_error "Examples: 'docker-fixes', 'api-patterns', 'pnpm-setup'"
exit 1
fi
# Validate output path to avoid writes outside current workspace.
if [[ "$SKILLS_DIR" = /* ]]; then
log_error "Output directory must be a relative path under the current directory."
exit 1
fi
if [[ "$SKILLS_DIR" =~ (^|/)\.\.(/|$) ]]; then
log_error "Output directory cannot include '..' path segments."
exit 1
fi
SKILLS_DIR="${SKILLS_DIR#./}"
SKILLS_DIR="./$SKILLS_DIR"
SKILL_PATH="$SKILLS_DIR/$SKILL_NAME"
# Check if skill already exists
if [ -d "$SKILL_PATH" ] && [ "$DRY_RUN" = false ]; then
log_error "Skill already exists: $SKILL_PATH"
log_error "Use a different name or remove the existing skill first."
exit 1
fi
# Dry run output
if [ "$DRY_RUN" = true ]; then
log_info "Dry run - would create:"
echo " $SKILL_PATH/"
echo " $SKILL_PATH/SKILL.md"
echo ""
echo "Template content would be:"
echo "---"
cat << TEMPLATE
name: $SKILL_NAME
description: "[TODO: Add a concise description of what this skill does and when to use it]"
---
# $(echo "$SKILL_NAME" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1')
[TODO: Brief introduction explaining the skill's purpose]
## Quick Reference
| Situation | Action |
|-----------|--------|
| [Trigger condition] | [What to do] |
## Usage
[TODO: Detailed usage instructions]
## Examples
[TODO: Add concrete examples]
## Source Learning
This skill was extracted from a learning entry.
- Learning ID: [TODO: Add original learning ID]
- Original File: .learnings/LEARNINGS.md
TEMPLATE
echo "---"
exit 0
fi
# Create skill directory structure
log_info "Creating skill: $SKILL_NAME"
mkdir -p "$SKILL_PATH"
# Create SKILL.md from template
cat > "$SKILL_PATH/SKILL.md" << TEMPLATE
---
name: $SKILL_NAME
description: "[TODO: Add a concise description of what this skill does and when to use it]"
---
# $(echo "$SKILL_NAME" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1')
[TODO: Brief introduction explaining the skill's purpose]
## Quick Reference
| Situation | Action |
|-----------|--------|
| [Trigger condition] | [What to do] |
## Usage
[TODO: Detailed usage instructions]
## Examples
[TODO: Add concrete examples]
## Source Learning
This skill was extracted from a learning entry.
- Learning ID: [TODO: Add original learning ID]
- Original File: .learnings/LEARNINGS.md
TEMPLATE
log_info "Created: $SKILL_PATH/SKILL.md"
# Suggest next steps
echo ""
log_info "Skill scaffold created successfully!"
echo ""
echo "Next steps:"
echo " 1. Edit $SKILL_PATH/SKILL.md"
echo " 2. Fill in the TODO sections with content from your learning"
echo " 3. Add references/ folder if you have detailed documentation"
echo " 4. Add scripts/ folder if you have executable code"
echo " 5. Update the original learning entry with:"
echo " **Status**: promoted_to_skill"
echo " **Skill-Path**: skills/$SKILL_NAME"