@coffeexdev/openclaw-sentinel 0.1.0

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.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +173 -0
  3. package/package.json +60 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 coffeebot-agent
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # @coffeexdev/openclaw-sentinel
2
+
3
+ Secure, declarative, gateway-native background watcher plugin for OpenClaw.
4
+
5
+ ## Why Sentinel
6
+
7
+ OpenClaw Sentinel runs watcher lifecycles inside the gateway using fixed strategies and declarative conditions.
8
+ It **does not** execute user-authored code from watcher definitions.
9
+
10
+ ## Features
11
+
12
+ - Tool registration: `sentinel_control`
13
+ - actions: `create`, `enable`, `disable`, `remove`, `status`, `list`
14
+ - Strict schema validation (`zod.strict`) + code-like field/value rejection
15
+ - Strategies:
16
+ - `http-poll`
17
+ - `websocket`
18
+ - `sse`
19
+ - `http-long-poll`
20
+ - Condition operators:
21
+ - `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `exists`, `absent`, `contains`, `matches`, `changed`
22
+ - Match mode: `all` / `any`
23
+ - Fire templating: substitution-only placeholders, non-Turing-complete
24
+ - Fire route: local internal webhook dispatch path (no outbound fire URL)
25
+ - Persistence: `~/.openclaw/sentinel-state.json`
26
+ - Resource limits and per-skill limits
27
+ - `allowedHosts` endpoint enforcement
28
+ - CLI surface: `list`, `status`, `enable`, `disable`, `audit`
29
+
30
+ ## JSON Schema
31
+
32
+ Formal JSON Schema for sentinel config/watchers is available at:
33
+
34
+ - `schema/sentinel.schema.json`
35
+
36
+ You can validate a watcher config document (for example `.sentinel.json`) against this schema in CI or local tooling.
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ npm i @coffeexdev/openclaw-sentinel
42
+ ```
43
+
44
+ ## Quick usage
45
+
46
+ ```ts
47
+ import { createSentinelPlugin } from "@coffeexdev/openclaw-sentinel";
48
+
49
+ const sentinel = createSentinelPlugin({
50
+ allowedHosts: ["api.github.com", "api.coingecko.com"],
51
+ localDispatchBase: "http://127.0.0.1:4389",
52
+ });
53
+
54
+ await sentinel.init();
55
+ sentinel.register({
56
+ registerTool(name, handler) {
57
+ // gateway tool registry hook
58
+ },
59
+ });
60
+ ```
61
+
62
+ ## Tool input example (`sentinel_control:create`)
63
+
64
+ ```json
65
+ {
66
+ "action": "create",
67
+ "watcher": {
68
+ "id": "sentinel-poker-alert",
69
+ "skillId": "skills.sentinel-poker",
70
+ "enabled": true,
71
+ "strategy": "http-poll",
72
+ "endpoint": "https://api.github.com/events",
73
+ "intervalMs": 15000,
74
+ "match": "any",
75
+ "conditions": [{ "path": "type", "op": "eq", "value": "PushEvent" }],
76
+ "fire": {
77
+ "webhookPath": "/internal/sentinel/fire",
78
+ "eventName": "sentinel-poker_push",
79
+ "payloadTemplate": {
80
+ "watcher": "${watcher.id}",
81
+ "event": "${event.name}",
82
+ "type": "${payload.type}",
83
+ "ts": "${timestamp}"
84
+ }
85
+ },
86
+ "retry": { "maxRetries": 5, "baseMs": 250, "maxMs": 5000 }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ## CLI
92
+
93
+ ```bash
94
+ openclaw-sentinel list
95
+ openclaw-sentinel status <watcher-id>
96
+ openclaw-sentinel enable <watcher-id>
97
+ openclaw-sentinel disable <watcher-id>
98
+ openclaw-sentinel audit
99
+ ```
100
+
101
+ ### One-shot watchers
102
+
103
+ Set `"fireOnce": true` to automatically disable a watcher after its first matched event.
104
+
105
+ ## Example scenarios
106
+
107
+ ### Sentinel Poker feed monitoring
108
+
109
+ Watch API changes and fire internal webhook events for orchestration.
110
+
111
+ ### Blockchain price watch
112
+
113
+ `http-poll` against `api.coingecko.com`, `gt/lte/changed` conditions, routed to local webhook.
114
+
115
+ ### CI monitoring
116
+
117
+ `sse` or `http-long-poll` against approved CI host endpoint; fire standardized internal events.
118
+
119
+ ## Security model
120
+
121
+ - No dynamic code execution from watcher definitions
122
+ - No dynamic imports/requires from definitions
123
+ - Strict input schema, unknown field rejection
124
+ - Code-like fields/values rejected
125
+ - Allowed-host enforcement on endpoints
126
+ - Local-only fire routing through `localDispatchBase + webhookPath`
127
+ - Bounded retries with backoff
128
+ - Global/per-skill/condition limits
129
+
130
+ ## Future Improvements
131
+
132
+ 1. **WebSocket/SSE resilience tuning**
133
+ - Improve reconnect behavior and dedupe close+error failure handling.
134
+ - Add stronger circuit-breaker/backoff controls under bursty failures.
135
+
136
+ 2. **State persistence hardening**
137
+ - Add optional payload redaction or `do-not-persist-payload` mode so `lastPayload` does not store sensitive data on disk.
138
+ - Keep `changed` semantics while minimizing persisted sensitive fields.
139
+
140
+ 3. **Dispatch integrity hardening**
141
+ - Add optional HMAC signing for internal webhook dispatch payloads in addition to bearer auth token support.
142
+ - Validate signature at receiver to prevent tampering in misconfigured local planes.
143
+
144
+ 4. **Regex safety simplification and compatibility policy**
145
+ - Continue standardizing on `re2` with `re2-wasm` fallback.
146
+ - Document/centralize behavior for unsupported regex features (e.g., lookahead/backrefs).
147
+
148
+ 5. **Lifecycle completeness**
149
+ - Add explicit `stopAll()` shutdown path in plugin lifecycle hooks for deterministic cleanup.
150
+ - Expand startup/reload behavior tests to ensure no orphaned watchers/timers.
151
+
152
+ 6. **Test coverage expansion (priority)**
153
+ - Add websocket reconnection/error-dedupe tests.
154
+ - Add retry/backoff timing behavior tests.
155
+ - Add state file permission assertions and payload persistence tests.
156
+ - Add dispatch auth matrix tests (token on/off).
157
+
158
+ ## Development
159
+
160
+ ```bash
161
+ npm i
162
+ npm run lint
163
+ npm run test
164
+ npm run build
165
+ ```
166
+
167
+ ## License
168
+
169
+ MIT
170
+
171
+ CI trigger probe: 2026-03-03T22:51:37Z
172
+
173
+ Push trigger probe 2026-03-03T22:56:44Z
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@coffeexdev/openclaw-sentinel",
3
+ "version": "0.1.0",
4
+ "description": "Secure declarative gateway-native watcher plugin for OpenClaw",
5
+ "keywords": [
6
+ "openclaw",
7
+ "plugin",
8
+ "security",
9
+ "sentinel",
10
+ "watcher"
11
+ ],
12
+ "license": "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/coffeexcoin/openclaw-sentinel.git"
16
+ },
17
+ "bin": {
18
+ "openclaw-sentinel": "dist/cli.js"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "type": "module",
26
+ "main": "dist/index.js",
27
+ "types": "dist/index.d.ts",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "scripts": {
32
+ "build": "tsc -p tsconfig.json",
33
+ "test": "vitest run",
34
+ "lint": "tsc --noEmit",
35
+ "format": "oxfmt --write .",
36
+ "format:check": "oxfmt --check .",
37
+ "changeset": "changeset",
38
+ "version-packages": "changeset version",
39
+ "release": "changeset publish"
40
+ },
41
+ "dependencies": {
42
+ "re2-wasm": "^1.0.2",
43
+ "ws": "^8.18.3",
44
+ "zod": "^3.24.1"
45
+ },
46
+ "devDependencies": {
47
+ "@changesets/cli": "^2.29.7",
48
+ "@types/node": "^24.0.0",
49
+ "@types/ws": "^8.5.13",
50
+ "oxfmt": "^0.36.0",
51
+ "typescript": "^5.8.2",
52
+ "vitest": "^3.0.8"
53
+ },
54
+ "optionalDependencies": {
55
+ "re2": "^1.23.3"
56
+ },
57
+ "engines": {
58
+ "node": ">=20"
59
+ }
60
+ }