@elvatis_com/openclaw-self-healing-elvatis 0.2.8 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ai/handoff/CONVENTIONS.md +96 -0
- package/.ai/handoff/DASHBOARD.md +38 -13
- package/.ai/handoff/LOG.md +61 -3
- package/.ai/handoff/NEXT_ACTIONS.md +25 -34
- package/.ai/handoff/STATUS.md +34 -20
- package/.clawhubignore +8 -0
- package/README.md +31 -15
- package/SKILL.md +2 -0
- package/index.ts +9 -3
- package/openclaw.plugin.json +2 -2
- package/package.json +2 -2
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# CONVENTIONS.md — openclaw-self-healing-elvatis
|
|
2
|
+
|
|
3
|
+
## Language & Runtime
|
|
4
|
+
- TypeScript strict mode, ESM (`"type": "module"`)
|
|
5
|
+
- Node 16 module resolution (`"moduleResolution": "Node16"`)
|
|
6
|
+
- Target: ES2022
|
|
7
|
+
|
|
8
|
+
## Package
|
|
9
|
+
- Scope: `@elvatis_com/openclaw-self-healing-elvatis`
|
|
10
|
+
- Plugin ID: `openclaw-self-healing-elvatis`
|
|
11
|
+
- Test runner: vitest
|
|
12
|
+
|
|
13
|
+
## File Layout
|
|
14
|
+
```
|
|
15
|
+
.ai/handoff/ ← AAHP protocol files (this folder)
|
|
16
|
+
src/ ← (future) extracted helpers
|
|
17
|
+
index.ts ← plugin entry point + all business logic
|
|
18
|
+
test/ ← vitest test suites
|
|
19
|
+
openclaw.plugin.json ← manifest
|
|
20
|
+
package.json / tsconfig.json / tsconfig.check.json
|
|
21
|
+
scripts/ ← one-off utilities (roadmap issue creation, etc.)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Code Style
|
|
25
|
+
- Named exports for all pure helpers (testable without plugin API)
|
|
26
|
+
- `saveState()` must be called BEFORE any destructive system call (e.g. `openclaw gateway restart`)
|
|
27
|
+
→ Reason: systemd-managed gateway restarts kill the process mid-execution; state written after the call is never persisted
|
|
28
|
+
- No secrets in logs — redact with `[REDACTED]`
|
|
29
|
+
- `runCmd` always uses `bash -lc` for login shell compatibility
|
|
30
|
+
- All `autoFix.*` flags default to the safest value (`false` unless stated otherwise)
|
|
31
|
+
- `whatsappRestartEnabled` is the one exception — defaults to `true` (most useful default)
|
|
32
|
+
|
|
33
|
+
## Release Checklist (mandatory for every publish)
|
|
34
|
+
|
|
35
|
+
### Before release
|
|
36
|
+
1. `npm run typecheck` — must pass
|
|
37
|
+
2. `npm test` — all tests must pass
|
|
38
|
+
3. Bump version in `package.json` AND `openclaw.plugin.json`
|
|
39
|
+
|
|
40
|
+
### Publish (all three platforms, no exceptions)
|
|
41
|
+
4. `git tag vX.Y.Z && git push origin main && git push origin vX.Y.Z`
|
|
42
|
+
5. `gh release create vX.Y.Z --title "..." --notes "..."`
|
|
43
|
+
6. `npm publish --access public`
|
|
44
|
+
7. ClawHub (use rsync workaround — `.clawhubignore` is NOT respected by `clawhub publish`):
|
|
45
|
+
```bash
|
|
46
|
+
TMP=$(mktemp -d)
|
|
47
|
+
rsync -a --exclude='node_modules' --exclude='.git' --exclude='dist' \
|
|
48
|
+
--exclude='package-lock.json' ./ "$TMP/"
|
|
49
|
+
clawhub publish "$TMP" --slug openclaw-self-healing-elvatis \
|
|
50
|
+
--name "OpenClaw Self Healing" --version X.Y.Z --changelog "..." --no-input
|
|
51
|
+
rm -rf "$TMP"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### After release
|
|
55
|
+
8. Update ALL docs in this repo: STATUS.md, DASHBOARD.md, LOG.md, NEXT_ACTIONS.md, README.md, SKILL.md
|
|
56
|
+
9. Update MEMORY.md on server if architecture decisions changed
|
|
57
|
+
|
|
58
|
+
## Documentation Rule (MANDATORY)
|
|
59
|
+
**Every release MUST update the following files before committing:**
|
|
60
|
+
- `.ai/handoff/STATUS.md` — current version, state, open risks
|
|
61
|
+
- `.ai/handoff/DASHBOARD.md` — task table
|
|
62
|
+
- `.ai/handoff/LOG.md` — append entry for this session
|
|
63
|
+
- `.ai/handoff/NEXT_ACTIONS.md` — move done tasks, add new ones
|
|
64
|
+
- `README.md` — version number + any changed behavior
|
|
65
|
+
- `SKILL.md` — if commands or config changed
|
|
66
|
+
|
|
67
|
+
Skipping documentation = incomplete release. No exceptions.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 🚨 Release-Regel: Erst fertig, dann publishen (gilt für ALLE Plattformen)
|
|
72
|
+
|
|
73
|
+
**IMMER erst alles fertigstellen, danach publishen. Kein einziger Commit mehr dazwischen.**
|
|
74
|
+
Gilt für GitHub, npm, ClawHub, PyPI — egal ob ein Projekt auf einer oder mehreren Plattformen ist.
|
|
75
|
+
Sonst divergieren die Tarballs/Releases zwangsläufig.
|
|
76
|
+
|
|
77
|
+
### Reihenfolge (nie abweichen)
|
|
78
|
+
1. Alle Änderungen + Versionsbumps in **einem einzigen Commit** abschließen
|
|
79
|
+
2. `git push` → Plattform 1 (z.B. GitHub)
|
|
80
|
+
3. `npm publish` / `clawhub publish` / etc. — alle weiteren Plattformen
|
|
81
|
+
4. Kein weiterer Commit bis zum nächsten Release (außer reine interne Doku)
|
|
82
|
+
|
|
83
|
+
### Vor jedem Release: Alle Versionsstellen prüfen
|
|
84
|
+
```bash
|
|
85
|
+
grep -rn "X\.Y\.Z\|Current version\|Version:" \
|
|
86
|
+
--include="*.md" --include="*.json" \
|
|
87
|
+
--exclude-dir=node_modules --exclude-dir=dist --exclude-dir=.git
|
|
88
|
+
```
|
|
89
|
+
Typische vergessene Stellen: `README.md` Header, `SKILL.md` Footer, `package.json`,
|
|
90
|
+
`openclaw.plugin.json`, `.ai/handoff/STATUS.md` (Header + Plattform-Zeilen), Changelog-Eintrag.
|
|
91
|
+
|
|
92
|
+
### Secrets & private Pfade — NIEMALS in Repos
|
|
93
|
+
- Keine API Keys, Tokens, Passwörter, Secrets in Code oder Docs
|
|
94
|
+
- Keine absoluten lokalen Pfade (`/home/user/...`) in publizierten Dateien
|
|
95
|
+
- Keine `.env`-Dateien committen — immer in `.gitignore`
|
|
96
|
+
- Vor jedem Push: `git diff --staged` auf Secrets prüfen
|
package/.ai/handoff/DASHBOARD.md
CHANGED
|
@@ -1,13 +1,38 @@
|
|
|
1
|
-
# DASHBOARD
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
|
1
|
+
# DASHBOARD.md — openclaw-self-healing-elvatis
|
|
2
|
+
|
|
3
|
+
_Last updated: 2026-03-07_
|
|
4
|
+
|
|
5
|
+
## 🏗️ Plugin Status
|
|
6
|
+
|
|
7
|
+
| Component | Version | Build | Tests | Status |
|
|
8
|
+
|-----------|---------|-------|-------|--------|
|
|
9
|
+
| openclaw-self-healing-elvatis | 0.2.8 | ✅ | 181/181 ✅ | ✅ Stable |
|
|
10
|
+
|
|
11
|
+
## 🚀 Release State
|
|
12
|
+
|
|
13
|
+
| Platform | Version | Status |
|
|
14
|
+
|----------|---------|--------|
|
|
15
|
+
| GitHub | v0.2.8 | ✅ Tagged + Release |
|
|
16
|
+
| npm | 0.2.8 | ✅ Published |
|
|
17
|
+
| ClawHub | 0.2.8 | ✅ Published |
|
|
18
|
+
|
|
19
|
+
## 📋 Open Tasks
|
|
20
|
+
|
|
21
|
+
| ID | Task | Priority | Status |
|
|
22
|
+
|----|------|----------|--------|
|
|
23
|
+
| T-014 | Export heal metrics to `~/.aahp/metrics.jsonl` | 🟡 MEDIUM | Ready |
|
|
24
|
+
|
|
25
|
+
## ✅ Completed Tasks
|
|
26
|
+
|
|
27
|
+
| Task | Title | Version |
|
|
28
|
+
|------|-------|---------|
|
|
29
|
+
| T-015 | Fix infinite gateway restart loop (lastRestartAt before restart) | 0.2.8 |
|
|
30
|
+
| T-005 | Plugin health monitoring via JSON API + auto-disable | 0.2.7 |
|
|
31
|
+
| T-013 | Status snapshot file on each monitor tick | 0.2.6 |
|
|
32
|
+
| T-012 | Startup config validation (fail-fast) | 0.2.6 |
|
|
33
|
+
| T-011 | Integration tests for monitor tick flows | 0.2.6 |
|
|
34
|
+
| T-004 | TypeScript build pipeline + typecheck | 0.2.5 |
|
|
35
|
+
| T-010 | Observability events + status endpoint | 0.2.4 |
|
|
36
|
+
| T-009 | Dry-run mode | 0.2.3 |
|
|
37
|
+
| T-008 | Active recovery probing | 0.2.3 |
|
|
38
|
+
| T-007 | Config hot-reload | 0.2.3 |
|
package/.ai/handoff/LOG.md
CHANGED
|
@@ -1,4 +1,62 @@
|
|
|
1
|
-
# LOG
|
|
1
|
+
# LOG.md — openclaw-self-healing-elvatis
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
## 2026-03-07 — Session (Akido / claude-sonnet-4-6)
|
|
4
|
+
|
|
5
|
+
**Bug: Infinite gateway restart loop (fixed in v0.2.8)**
|
|
6
|
+
|
|
7
|
+
Root cause: `openclaw gateway restart` kills the process via systemd. `lastRestartAt = nowSec()`,
|
|
8
|
+
`disconnectStreak = 0`, and `saveState()` were placed AFTER `runCmd("openclaw gateway restart")`.
|
|
9
|
+
These lines never executed when the process was killed. On next boot, `lastRestartAt = 0`,
|
|
10
|
+
`since = huge`, bypassing the 5-minute rate-limit guard. WhatsApp takes 60–120s to reconnect
|
|
11
|
+
after any restart → self-healing saw 2 disconnect ticks → hit threshold → restarted again.
|
|
12
|
+
Infinite loop.
|
|
13
|
+
|
|
14
|
+
Fix: moved `lastRestartAt = nowSec()`, `disconnectStreak = 0`, and `saveState()` to BEFORE
|
|
15
|
+
the `runCmd("openclaw gateway restart")` call.
|
|
16
|
+
|
|
17
|
+
**Release pipeline:**
|
|
18
|
+
- v0.2.8 committed, tagged, pushed to GitHub
|
|
19
|
+
- GitHub release created: https://github.com/elvatis/openclaw-self-healing-elvatis/releases/tag/v0.2.8
|
|
20
|
+
- npm published: `@elvatis_com/openclaw-self-healing-elvatis@0.2.8`
|
|
21
|
+
- ClawHub published: `openclaw-self-healing-elvatis@0.2.8` (rsync workaround — .clawhubignore not respected by clawhub publish)
|
|
22
|
+
- Added `.clawhubignore` and documented rsync workaround in CONVENTIONS.md
|
|
23
|
+
|
|
24
|
+
All 181 tests passed before release.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2026-03-02 — Session (Akido)
|
|
29
|
+
|
|
30
|
+
- T-013: Status snapshot file written on each monitor tick
|
|
31
|
+
- T-012: Startup config validation with fail-fast
|
|
32
|
+
- T-011: Integration tests for monitor service tick flows
|
|
33
|
+
- T-005: Plugin health monitoring implemented via `openclaw plugins list --json`
|
|
34
|
+
- Atomic state writes (tmp + rename)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 2026-03-01 — Session (Akido)
|
|
39
|
+
|
|
40
|
+
- T-004: TypeScript build pipeline + typecheck
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 2026-02-28 — Session (Akido)
|
|
45
|
+
|
|
46
|
+
- T-010: Self-heal status endpoint / observability events
|
|
47
|
+
- T-009: Dry-run mode
|
|
48
|
+
- T-008: Active recovery probing
|
|
49
|
+
- T-007: Config hot-reload
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 2026-02-27 — Session (Akido)
|
|
54
|
+
|
|
55
|
+
- Defined v0.3 roadmap with 8 items. Created ROADMAP.md + scripts/create-roadmap-issues.sh.
|
|
56
|
+
- GitHub issue creation deferred (gh CLI not authenticated at the time).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 2026-02-24 — Session (Akido)
|
|
61
|
+
|
|
62
|
+
- Initialized AAHP handoff structure.
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
# NEXT_ACTIONS
|
|
1
|
+
# NEXT_ACTIONS.md — openclaw-self-healing-elvatis
|
|
2
|
+
|
|
3
|
+
_Last updated: 2026-03-07_
|
|
2
4
|
|
|
3
5
|
## Status Summary
|
|
4
6
|
|
|
5
|
-
| Status
|
|
6
|
-
|
|
7
|
-
| Done
|
|
8
|
-
| Ready
|
|
9
|
-
| Blocked |
|
|
7
|
+
| Status | Count |
|
|
8
|
+
|--------|-------|
|
|
9
|
+
| Done | 15 |
|
|
10
|
+
| Ready | 1 |
|
|
11
|
+
| Blocked | 0 |
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
13
|
-
## Ready
|
|
15
|
+
## Ready — Work These Next
|
|
14
16
|
|
|
15
|
-
### T-014: [medium]
|
|
16
|
-
- **Goal:** Append one JSONL line per heal event
|
|
17
|
-
- **Context:** Heal events are
|
|
17
|
+
### T-014: [medium] — Export heal metrics to `~/.aahp/metrics.jsonl`
|
|
18
|
+
- **Goal:** Append one JSONL line per heal event for analysis and alerting.
|
|
19
|
+
- **Context:** Heal events are only visible in logs and via `api.emit()`. No persistent record for analysis.
|
|
18
20
|
- **What to do:**
|
|
19
21
|
- Export `appendMetric(line, metricsFile)` helper
|
|
20
|
-
- Write entries for: model-cooldown
|
|
22
|
+
- Write entries for: `model-cooldown`, `session-patched`, `whatsapp-restart`, `cron-disabled`, `model-recovered`
|
|
21
23
|
- Default metrics file: `~/.aahp/metrics.jsonl` (configurable via `metricsFile`)
|
|
22
24
|
- Skip or mark dry-run events
|
|
23
25
|
- Create parent directory if missing
|
|
@@ -27,28 +29,17 @@
|
|
|
27
29
|
|
|
28
30
|
---
|
|
29
31
|
|
|
30
|
-
## Blocked
|
|
31
|
-
|
|
32
|
-
### T-005: [high] - Implement structured plugin health monitoring and auto-disable (issue #3)
|
|
33
|
-
- **Blocked by:** Waiting for `openclaw plugins list --json` API from openclaw core
|
|
34
|
-
- **Goal:** Monitor plugin health and auto-disable failing plugins using structured JSON output.
|
|
35
|
-
- **Context:** Current code has a stub that parses plain text output from `openclaw plugins list`. No robust parsing is possible without the `--json` flag.
|
|
36
|
-
- **What to do (when unblocked):**
|
|
37
|
-
- Parse `openclaw plugins list --json` output for plugin status
|
|
38
|
-
- Auto-disable plugins with `status=error` (respecting `pluginDisableCooldownSec`)
|
|
39
|
-
- Create GitHub issues for disabled plugins
|
|
40
|
-
- **Files:** `index.ts`, `test/index.test.ts`
|
|
41
|
-
- **Definition of done:** Failing plugins are detected via JSON API and auto-disabled; tests cover detection and disable logic.
|
|
42
|
-
- **GitHub Issue:** #3
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
32
|
## Recently Completed
|
|
47
33
|
|
|
48
|
-
| Task
|
|
49
|
-
|
|
50
|
-
| T-
|
|
51
|
-
| T-
|
|
52
|
-
| T-
|
|
53
|
-
| T-
|
|
54
|
-
| T-
|
|
34
|
+
| Task | Title | Date |
|
|
35
|
+
|------|-------|------|
|
|
36
|
+
| T-015 | Fix infinite gateway restart loop | 2026-03-07 |
|
|
37
|
+
| T-005 | Plugin health monitoring via JSON API | 2026-03-07 |
|
|
38
|
+
| T-013 | Status snapshot file on each monitor tick | 2026-03-02 |
|
|
39
|
+
| T-012 | Startup config validation (fail-fast) | 2026-03-02 |
|
|
40
|
+
| T-011 | Integration tests for monitor tick flows | 2026-03-02 |
|
|
41
|
+
| T-004 | TypeScript build pipeline + typecheck | 2026-03-01 |
|
|
42
|
+
| T-010 | Observability events + status endpoint | 2026-02-28 |
|
|
43
|
+
| T-009 | Dry-run mode | 2026-02-28 |
|
|
44
|
+
| T-008 | Active recovery probing | 2026-02-28 |
|
|
45
|
+
| T-007 | Config hot-reload | 2026-02-28 |
|
package/.ai/handoff/STATUS.md
CHANGED
|
@@ -1,20 +1,34 @@
|
|
|
1
|
-
# STATUS
|
|
2
|
-
|
|
3
|
-
(
|
|
4
|
-
|
|
5
|
-
## Current
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
1
|
+
# STATUS.md — openclaw-self-healing-elvatis
|
|
2
|
+
|
|
3
|
+
_Last updated: 2026-03-08 by Akido (claude-sonnet-4-6)_
|
|
4
|
+
|
|
5
|
+
## Current Version: 0.2.10 — STABLE
|
|
6
|
+
|
|
7
|
+
## What is done
|
|
8
|
+
|
|
9
|
+
- ✅ Repo: `https://github.com/elvatis/openclaw-self-healing-elvatis`
|
|
10
|
+
- ✅ npm: `@elvatis_com/openclaw-self-healing-elvatis@0.2.10`
|
|
11
|
+
- ✅ ClawHub: `openclaw-self-healing-elvatis@0.2.10`
|
|
12
|
+
- ✅ Model failover: rate-limit + auth-scope cooldown, configurable fallback order
|
|
13
|
+
- ✅ WhatsApp reconnect: disconnect streak detection + gateway restart
|
|
14
|
+
- ✅ Cron failure: consecutive fail threshold → disable + GitHub issue
|
|
15
|
+
- ✅ Plugin health monitoring: `openclaw plugins list --json` → auto-disable on crash/error
|
|
16
|
+
- ✅ Config guardrails: never modify/restart if `openclaw.json` is invalid JSON
|
|
17
|
+
- ✅ Startup config validation (fail-fast)
|
|
18
|
+
- ✅ Status snapshot: written to file on every tick for external monitoring
|
|
19
|
+
- ✅ Active recovery probing: polls limited models to detect early recovery
|
|
20
|
+
- ✅ Dry-run mode: full behavior simulation without side effects
|
|
21
|
+
- ✅ Backup path: `~/.openclaw/backups/openclaw.json/openclaw.json.<timestamp>.bak`
|
|
22
|
+
|
|
23
|
+
## Backup Behavior
|
|
24
|
+
|
|
25
|
+
The plugin creates timestamped backups before any action that could restart the gateway
|
|
26
|
+
or change cron/plugin state. Backups are written to:
|
|
27
|
+
`~/.openclaw/backups/openclaw.json/openclaw.json.<ISO-timestamp>.bak`
|
|
28
|
+
|
|
29
|
+
Note: Files like `openclaw.json.bak` in `~/.openclaw/` are from the manual config-change
|
|
30
|
+
checklist procedure, not from this plugin.
|
|
31
|
+
|
|
32
|
+
## Open Risks
|
|
33
|
+
|
|
34
|
+
- ClawHub publish ignores `.clawhubignore` — use rsync workaround (see CONVENTIONS.md)
|
package/.clawhubignore
ADDED
package/README.md
CHANGED
|
@@ -1,27 +1,43 @@
|
|
|
1
1
|
# openclaw-self-healing-elvatis
|
|
2
2
|
|
|
3
|
+
**Current version: `0.2.10`**
|
|
4
|
+
|
|
3
5
|
OpenClaw plugin that improves resilience by automatically fixing reversible failures.
|
|
4
6
|
|
|
5
|
-
## What it
|
|
7
|
+
## What it heals
|
|
8
|
+
|
|
9
|
+
- **Model outage** — Detect rate limit / quota / auth-scope failures, put model into cooldown, patch pinned session to a safe fallback
|
|
10
|
+
- **WhatsApp disconnect** — If WhatsApp appears disconnected repeatedly: restart the gateway (streak threshold + minimum restart interval guard)
|
|
11
|
+
- **Cron failures** — If a cron job fails repeatedly: disable it + create a GitHub issue
|
|
12
|
+
- **Plugin crashes** — If a plugin reports `status=error` or `status=crash`: auto-disable + GitHub issue
|
|
13
|
+
|
|
14
|
+
## Changelog
|
|
15
|
+
|
|
16
|
+
### v0.2.10 — 2026-03-08
|
|
17
|
+
Docs fix: README and STATUS.md version headers were stuck at 0.2.8 after v0.2.9 bump; SKILL.md missing version footer; add universal release-rule to CONVENTIONS.md.
|
|
6
18
|
|
|
7
|
-
|
|
19
|
+
### v0.2.9 — 2026-03-07
|
|
20
|
+
**Fix: Plugin health monitoring JSON parsing**
|
|
21
|
+
Extract JSON from stdout before parsing — channels subprocess output includes
|
|
22
|
+
non-JSON log lines (e.g. `[INFO] ...`) before the JSON payload, causing parse
|
|
23
|
+
failures in plugin health checks.
|
|
8
24
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
25
|
+
### v0.2.8 — 2026-03-07
|
|
26
|
+
**Fix: Infinite gateway restart loop**
|
|
27
|
+
`lastRestartAt` and `disconnectStreak` are now saved to disk **before** calling
|
|
28
|
+
`openclaw gateway restart`. Previously they were saved after, but systemd kills
|
|
29
|
+
the process during restart — state was never persisted, the rate-limit guard was
|
|
30
|
+
bypassed on every boot, causing an infinite restart loop when used alongside
|
|
31
|
+
any plugin that triggers a config-driven gateway restart (e.g. `openclaw-cli-bridge-elvatis`).
|
|
13
32
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- Guardrails: streak threshold + minimum restart interval
|
|
33
|
+
### v0.2.7 — 2026-03-07
|
|
34
|
+
Fix `runCommandWithTimeout` call signature + field name.
|
|
17
35
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Create a GitHub issue with last error context (rate limited)
|
|
36
|
+
### v0.2.6 — 2026-03-02
|
|
37
|
+
Status snapshot file, startup config validation, integration tests.
|
|
21
38
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- Waiting for `openclaw plugins list --json` or an equivalent stable API
|
|
39
|
+
### v0.2.5 and earlier
|
|
40
|
+
Model failover, WhatsApp reconnect, cron failure, dry-run mode, active recovery probing, config hot-reload.
|
|
25
41
|
|
|
26
42
|
## Install
|
|
27
43
|
|
package/SKILL.md
CHANGED
package/index.ts
CHANGED
|
@@ -618,7 +618,11 @@ export default function register(api: any) {
|
|
|
618
618
|
if (config.whatsappRestartEnabled) {
|
|
619
619
|
const st = await runCmd(api, "openclaw channels status --json", 15000);
|
|
620
620
|
if (st.ok) {
|
|
621
|
-
|
|
621
|
+
// openclaw CLI prints plugin startup lines (e.g. "[plugins] [self-heal] enabled...")
|
|
622
|
+
// to stdout before the JSON payload. Extract the first JSON object to avoid
|
|
623
|
+
// safeJsonParse returning undefined and falsely treating WA as disconnected.
|
|
624
|
+
const jsonMatch = st.stdout.match(/\{[\s\S]*\}/);
|
|
625
|
+
const parsed = jsonMatch ? safeJsonParse<any>(jsonMatch[0]) : undefined;
|
|
622
626
|
const wa = parsed?.channels?.whatsapp;
|
|
623
627
|
const connected = wa?.status === "connected" || wa?.connected === true;
|
|
624
628
|
|
|
@@ -678,7 +682,8 @@ export default function register(api: any) {
|
|
|
678
682
|
if (config.disableFailingCrons) {
|
|
679
683
|
const res = await runCmd(api, "openclaw cron list --json", 15000);
|
|
680
684
|
if (res.ok) {
|
|
681
|
-
const
|
|
685
|
+
const cronJsonMatch = res.stdout.match(/\{[\s\S]*\}/);
|
|
686
|
+
const parsed = cronJsonMatch ? safeJsonParse<any>(cronJsonMatch[0]) : undefined;
|
|
682
687
|
const jobs: any[] = parsed?.jobs ?? [];
|
|
683
688
|
for (const job of jobs) {
|
|
684
689
|
const id = job.id;
|
|
@@ -767,7 +772,8 @@ export default function register(api: any) {
|
|
|
767
772
|
const res = await runCmd(api, "openclaw plugins list --json", 15000);
|
|
768
773
|
if (res.ok) {
|
|
769
774
|
type PluginEntry = { id: string; name?: string; enabled?: boolean; status?: string; version?: string; error?: string };
|
|
770
|
-
const
|
|
775
|
+
const pluginJsonMatch = res.stdout.match(/\{[\s\S]*\}/);
|
|
776
|
+
const parsed = pluginJsonMatch ? safeJsonParse<{ plugins: PluginEntry[] }>(pluginJsonMatch[0]) : undefined;
|
|
771
777
|
const plugins: PluginEntry[] = parsed?.plugins ?? [];
|
|
772
778
|
const selfId = "openclaw-self-healing-elvatis";
|
|
773
779
|
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "openclaw-self-healing-elvatis",
|
|
3
3
|
"name": "OpenClaw Self Healing",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.10",
|
|
5
5
|
"description": "Self-healing health checks + guardrails + auto-fix for reversible failures (rate limits, auth errors, stuck session pins).",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
@@ -107,4 +107,4 @@
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
}
|
|
110
|
+
}
|
package/package.json
CHANGED