@mapick/cost-firewall 0.1.0 → 0.1.1
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/README.md +56 -68
- package/dist/provider/auth.d.ts.map +1 -1
- package/dist/provider/auth.js +11 -3
- package/dist/provider/auth.js.map +1 -1
- package/dist/provider/index.d.ts +8 -0
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +8 -0
- package/dist/provider/index.js.map +1 -1
- package/dist/store.d.ts +2 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +6 -12
- package/dist/store.js.map +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -11,6 +11,12 @@ AI Call Firewall — real-time monitoring, budget control, automatic circuit bre
|
|
|
11
11
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
14
|
+
**One-click:**
|
|
15
|
+
```bash
|
|
16
|
+
curl -fsSL https://raw.githubusercontent.com/mapick-ai/cost-firewall/main/install.sh | bash
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Manual:**
|
|
14
20
|
```bash
|
|
15
21
|
openclaw plugins install @mapick/cost-firewall
|
|
16
22
|
openclaw plugins enable mapick-firewall
|
|
@@ -24,15 +30,19 @@ Dashboard: **http://localhost:18789/mapick/dashboard**
|
|
|
24
30
|
|
|
25
31
|
## Commands
|
|
26
32
|
|
|
27
|
-
|
|
|
28
|
-
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
33
|
+
| CLI | Action |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `openclaw firewall status` | View status (mode, tokens, blocked, limit) |
|
|
36
|
+
| `openclaw firewall stop` | 🛑 Emergency stop — block all AI calls |
|
|
37
|
+
| `openclaw firewall resume` | ▶️ Resume after stop |
|
|
38
|
+
| `openclaw firewall mode observe` | Observe mode — record only, no blocking |
|
|
39
|
+
| `openclaw firewall mode protect` | Protect mode — enable all breaker rules |
|
|
40
|
+
| `openclaw firewall budget set 50000` | Set daily token limit to 50K |
|
|
41
|
+
| `openclaw firewall budget reset` | Remove daily token limit |
|
|
42
|
+
| `openclaw firewall log --last 20` | Show last 20 events |
|
|
43
|
+
| `openclaw firewall reset <source>` | Reset a source from cooldown |
|
|
44
|
+
|
|
45
|
+
In OpenClaw chat: `/firewall status`, `/firewall stop`, `/firewall resume`, `/firewall log`
|
|
36
46
|
|
|
37
47
|
---
|
|
38
48
|
|
|
@@ -63,99 +73,77 @@ Dashboard: **http://localhost:18789/mapick/dashboard**
|
|
|
63
73
|
|
|
64
74
|
---
|
|
65
75
|
|
|
66
|
-
##
|
|
76
|
+
## Breaking Rules
|
|
77
|
+
|
|
78
|
+
Firewall has two modes: **Observe** (record, don't block) and **Protect** (active blocking).
|
|
79
|
+
|
|
80
|
+
| Rule | Trigger | Effect |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| Emergency Stop | `openclaw firewall stop` | Block all calls |
|
|
83
|
+
| Daily Token Limit | Today's tokens ≥ limit | Block all calls |
|
|
84
|
+
| Consecutive Failures | N failures in a row | Block source for cooldown |
|
|
85
|
+
| Token Velocity | N tokens in W seconds | Block source for cooldown |
|
|
86
|
+
| Call Frequency | N calls in W seconds | Block source for cooldown |
|
|
87
|
+
|
|
88
|
+
### Defaults
|
|
67
89
|
|
|
68
90
|
| Rule | Threshold | Window | Cooldown |
|
|
69
91
|
|---|---|---|---|
|
|
70
92
|
| Consecutive Failures | 3 | — | 30s |
|
|
71
93
|
| Token Velocity | 100K tokens | 60s | 30s |
|
|
72
94
|
| Call Frequency | 30 calls | 60s | 30s |
|
|
73
|
-
| Daily Token Limit | unlimited | — | — |
|
|
95
|
+
| Daily Token Limit | None (unlimited) | — | — |
|
|
74
96
|
|
|
75
97
|
---
|
|
76
98
|
|
|
77
99
|
## AI Installation Checklist
|
|
78
100
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```markdown
|
|
82
|
-
## Installation Steps
|
|
83
|
-
|
|
84
|
-
1. Install the npm package:
|
|
85
|
-
```bash
|
|
86
|
-
openclaw plugins install @mapick/cost-firewall
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
2. Enable the plugin:
|
|
90
|
-
```bash
|
|
91
|
-
openclaw plugins enable mapick-firewall
|
|
92
|
-
```
|
|
101
|
+
Copy the entire block below and execute:
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
Expected: should show `mapick-firewall` in the list.
|
|
99
|
-
|
|
100
|
-
4. Restart gateway:
|
|
101
|
-
```bash
|
|
102
|
-
openclaw gateway restart
|
|
103
|
-
```
|
|
103
|
+
```bash
|
|
104
|
+
# 1. Install the plugin
|
|
105
|
+
openclaw plugins install @mapick/cost-firewall
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
openclaw firewall status
|
|
108
|
-
```
|
|
109
|
-
Expected: returns JSON with mode, today_tokens, today_blocked, etc.
|
|
107
|
+
# 2. Enable it
|
|
108
|
+
openclaw plugins enable mapick-firewall
|
|
110
109
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
openclaw firewall budget set 500000
|
|
114
|
-
```
|
|
110
|
+
# 3. Verify registration
|
|
111
|
+
openclaw plugins list | grep mapick-firewall
|
|
115
112
|
|
|
116
|
-
|
|
113
|
+
# 4. Restart gateway
|
|
114
|
+
openclaw gateway restart
|
|
117
115
|
|
|
118
|
-
|
|
116
|
+
# 5. Verify it works
|
|
117
|
+
openclaw firewall status
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"agents": {
|
|
123
|
-
"defaults": {
|
|
124
|
-
"model": {
|
|
125
|
-
"primary": "mapick/deepseek/deepseek-chat",
|
|
126
|
-
"fallbacks": ["mapick/anthropic/claude-sonnet-4-20250514"]
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
119
|
+
# 6. Optional: set a daily token budget
|
|
120
|
+
openclaw firewall budget set 500000
|
|
131
121
|
```
|
|
132
122
|
|
|
133
|
-
|
|
134
|
-
Supported upstreams: `openai`, `anthropic`, `deepseek`, `openrouter`, `qwen`
|
|
135
|
-
|
|
136
|
-
## Validation
|
|
137
|
-
|
|
138
|
-
After installation, the AI should verify:
|
|
123
|
+
After installation, verify:
|
|
139
124
|
- [ ] `openclaw plugins list` shows `mapick-firewall` (enabled)
|
|
140
125
|
- [ ] `openclaw firewall status` returns valid JSON
|
|
141
126
|
- [ ] Dashboard accessible at http://localhost:18789/mapick/dashboard
|
|
142
127
|
- [ ] Model config uses `mapick/` prefix if firewall protection is desired
|
|
143
128
|
- [ ] Fallbacks also use `mapick/` prefix (non-mapick fallbacks bypass the firewall)
|
|
144
|
-
```
|
|
145
129
|
|
|
146
130
|
---
|
|
147
131
|
|
|
148
|
-
##
|
|
132
|
+
## Known Limitations
|
|
133
|
+
|
|
134
|
+
- **Provider Layer**: `mapick/*` model routing is registered and unit-tested, but end-to-end gateway contract validation (createStreamFn invocation, synthetic stream delivery, fallback routing) is pending.
|
|
135
|
+
- **Message format**: Plain text calls work; tool calls, system prompts, and reasoning payloads may need format conversion for upstream APIs.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Dev
|
|
149
140
|
|
|
150
141
|
```bash
|
|
151
142
|
pnpm install
|
|
152
143
|
pnpm build
|
|
153
144
|
pnpm test
|
|
154
|
-
pnpm dev # tsc --watch
|
|
155
145
|
```
|
|
156
146
|
|
|
157
|
-
See [RELEASE.md](./RELEASE.md) for release process.
|
|
158
|
-
|
|
159
147
|
## License
|
|
160
148
|
|
|
161
149
|
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/provider/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAWD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/provider/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAWD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CA4CrB"}
|
package/dist/provider/auth.js
CHANGED
|
@@ -15,14 +15,22 @@ const ENV_VAR_MAP = {
|
|
|
15
15
|
qwen: "DASHSCOPE_API_KEY",
|
|
16
16
|
};
|
|
17
17
|
export async function resolveUpstreamAuth(api, upstream, model) {
|
|
18
|
+
// Helper: extract key from response (could be string or { apiKey, ... })
|
|
19
|
+
function extractKey(raw) {
|
|
20
|
+
if (!raw)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (typeof raw === "string")
|
|
23
|
+
return raw;
|
|
24
|
+
return raw.apiKey ?? raw.key ?? raw.value ?? undefined;
|
|
25
|
+
}
|
|
18
26
|
// 1. Try SDK runtime auth
|
|
19
27
|
if (api.runtime?.modelAuth?.getApiKeyForModel) {
|
|
20
28
|
try {
|
|
21
|
-
const key = await api.runtime.modelAuth.getApiKeyForModel({
|
|
29
|
+
const key = extractKey(await api.runtime.modelAuth.getApiKeyForModel({
|
|
22
30
|
model: { provider: upstream, id: model },
|
|
23
31
|
cfg: api.config,
|
|
24
32
|
workspaceDir: api.workspaceDir,
|
|
25
|
-
});
|
|
33
|
+
}));
|
|
26
34
|
if (key)
|
|
27
35
|
return { apiKey: key };
|
|
28
36
|
}
|
|
@@ -30,7 +38,7 @@ export async function resolveUpstreamAuth(api, upstream, model) {
|
|
|
30
38
|
}
|
|
31
39
|
if (api.runtime?.modelAuth?.resolveApiKeyForProvider) {
|
|
32
40
|
try {
|
|
33
|
-
const key = await api.runtime.modelAuth.resolveApiKeyForProvider(upstream);
|
|
41
|
+
const key = extractKey(await api.runtime.modelAuth.resolveApiKeyForProvider(upstream));
|
|
34
42
|
if (key)
|
|
35
43
|
return { apiKey: key };
|
|
36
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/provider/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,oCAAoC;AACpC,MAAM,WAAW,GAA2B;IAC1C,MAAM,EAAE,gBAAgB;IACxB,SAAS,EAAE,mBAAmB;IAC9B,UAAU,EAAE,oBAAoB;IAChC,QAAQ,EAAE,kBAAkB;IAC5B,IAAI,EAAE,mBAAmB;CAC1B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAQ,EACR,QAAgB,EAChB,KAAa;IAEb,0BAA0B;IAC1B,IAAI,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/provider/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,oCAAoC;AACpC,MAAM,WAAW,GAA2B;IAC1C,MAAM,EAAE,gBAAgB;IACxB,SAAS,EAAE,mBAAmB;IAC9B,UAAU,EAAE,oBAAoB;IAChC,QAAQ,EAAE,kBAAkB;IAC5B,IAAI,EAAE,mBAAmB;CAC1B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAQ,EACR,QAAgB,EAChB,KAAa;IAEb,yEAAyE;IACzE,SAAS,UAAU,CAAC,GAAQ;QAC1B,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC;QACxC,OAAO,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,IAAI,SAAS,CAAC;IACzD,CAAC;IAED,0BAA0B;IAC1B,IAAI,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,iBAAiB,CAAC;gBACnE,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE;gBACxC,GAAG,EAAE,GAAG,CAAC,MAAM;gBACf,YAAY,EAAE,GAAG,CAAC,YAAY;aAC/B,CAAC,CAAC,CAAC;YACJ,IAAI,GAAG;gBAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC;YACvF,IAAI,GAAG;gBAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC5B,CAAC;IAED,+BAA+B;IAC/B,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,QAAQ,CAAC,CAAC;IACjE,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC;IAC3C,CAAC;IAED,qCAAqC;IACrC,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAE,EAAE,CAAC;IAC1C,CAAC;IAED,MAAM,IAAI,KAAK,CACb,mDAAmD,QAAQ,KAAK;QAChE,8CAA8C,QAAQ,WAAW;QACjE,cAAc,WAAW,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,GAAG,UAAU,wBAAwB,CACnG,CAAC;AACJ,CAAC"}
|
package/dist/provider/index.d.ts
CHANGED
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
* - catalog: declare model catalog
|
|
6
6
|
* - resolveDynamicModel: dynamically accept any upstream model ID
|
|
7
7
|
* - createStreamFn: precheck + upstream forwarding
|
|
8
|
+
*
|
|
9
|
+
* @known-limitations
|
|
10
|
+
* - Message format: passes context.messages directly to upstream API.
|
|
11
|
+
* Works for plain text but tool calls, system prompts, cache headers,
|
|
12
|
+
* and reasoning payloads may need format conversion for Anthropic/OpenAI.
|
|
13
|
+
* - Provider contract: not yet validated against real OpenClaw gateway
|
|
14
|
+
* contract (createStreamFn invocation, synthetic stream handling, fallback
|
|
15
|
+
* routing). Works via runtime registration; end-to-end gateway test pending.
|
|
8
16
|
*/
|
|
9
17
|
import type { FirewallState } from "../state.js";
|
|
10
18
|
import type { EventStore } from "../store.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAoB9C,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,UAAU,GAChB,IAAI,CAuGN"}
|
package/dist/provider/index.js
CHANGED
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
* - catalog: declare model catalog
|
|
6
6
|
* - resolveDynamicModel: dynamically accept any upstream model ID
|
|
7
7
|
* - createStreamFn: precheck + upstream forwarding
|
|
8
|
+
*
|
|
9
|
+
* @known-limitations
|
|
10
|
+
* - Message format: passes context.messages directly to upstream API.
|
|
11
|
+
* Works for plain text but tool calls, system prompts, cache headers,
|
|
12
|
+
* and reasoning payloads may need format conversion for Anthropic/OpenAI.
|
|
13
|
+
* - Provider contract: not yet validated against real OpenClaw gateway
|
|
14
|
+
* contract (createStreamFn invocation, synthetic stream handling, fallback
|
|
15
|
+
* routing). Works via runtime registration; end-to-end gateway test pending.
|
|
8
16
|
*/
|
|
9
17
|
import { parseMapickModelRef } from "./route.js";
|
|
10
18
|
import { resolveUpstreamAuth } from "./auth.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,SAAS,eAAe,CAAC,GAAU;IACjC,MAAM,CAAC,GAAG,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IACvE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,YAAY,CAAC;IACzE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IACjE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,eAAe,CAAC;IACzE,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,cAAc,CAAC;IACpE,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACvF,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,eAAe,CAAC;IAChD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,GAAQ,EACR,KAAoB,EACpB,KAAiB;IAEjB,GAAG,CAAC,gBAAgB,CAAC;QACnB,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,sBAAsB;QAC7B,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,EAAE;QAER,OAAO,EAAE;YACP,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE,CAAC,CAAC;gBACzB,QAAQ,EAAE;oBACR,GAAG,EAAE,oBAAoB;oBACzB,OAAO,EAAE,0BAA0B;oBACnC,MAAM,EAAE,wBAAwB;oBAChC,MAAM,EAAE,CAAC;4BACP,EAAE,EAAE,gBAAgB;4BACpB,IAAI,EAAE,6BAA6B;4BACnC,SAAS,EAAE,KAAK;4BAChB,KAAK,EAAE,CAAC,MAAM,CAAC;4BACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;4BAC7B,aAAa,EAAE,MAAM;4BACrB,SAAS,EAAE,IAAI;yBAChB,CAAC;iBACH;aACF,CAAC;SACH;QAED,mBAAmB,EAAE,CAAC,GAAQ,EAAE,EAAE;YAChC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5F,OAAO;gBACL,EAAE,EAAE,OAAO;gBACX,IAAI,EAAE,YAAY,SAAS,EAAE;gBAC7B,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,oBAAoB;gBACzB,OAAO,EAAE,0BAA0B;gBACnC,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE,CAAC,MAAM,CAAC;gBACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;gBAC7B,aAAa,EAAE,MAAM;gBACrB,SAAS,EAAE,IAAI;aAChB,CAAC;QACJ,CAAC;QAED,cAAc;YACZ,MAAM,IAAI,GAAG,IAAI,CAAC;YAClB,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC,KAAU,EAAE,OAAY,EAAE,OAAY;gBAClE,4EAA4E;gBAC5E,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC;gBACpE,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;gBAC3C,IAAI,CAAC,KAAK;oBAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,EAAE,CAAC,CAAC;gBAE1E,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAE3B,mBAAmB;gBACnB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAEnC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClB,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;oBACjC,KAAK,CAAC,MAAM,CAAC;wBACX,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,MAAM,EAAE,MAAM,CAAC,MAAO;wBACtB,KAAK,EAAE,MAAM,CAAC,KAAK;qBACpB,CAAC,CAAC;oBACH,KAAK,CAAC,CAAC,mBAAmB,CAAC;wBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,MAAM,EAAE,MAAM,CAAC,MAAO;wBACtB,MAAM,EAAE,KAAK,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ;qBAChE,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBAED,wBAAwB;gBACxB,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBAEzE,IAAI,WAAW,GAAG,CAAC,CAAC;gBAAC,IAAI,YAAY,GAAG,CAAC,CAAC;gBAAC,IAAI,mBAAmB,GAAG,CAAC,CAAC;gBACvE,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,KAAK,WAAW;wBACtC,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;wBAC7G,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;oBAExJ,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;wBAC5B,mBAAmB,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;wBACpD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;4BAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,IAAI,WAAW,CAAC;4BAAC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,IAAI,YAAY,CAAC;wBAAC,CAAC;wBAC1I,MAAM,KAAK,CAAC;oBACd,CAAC;oBAED,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;oBAC7I,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;oBACpI,KAAK,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;oBACnC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gBACnC,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,MAAM,GAAG,GAAG,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;oBACxC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;oBACzK,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;oBACjC,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/dist/store.d.ts
CHANGED
|
@@ -8,12 +8,11 @@ export declare class EventStore {
|
|
|
8
8
|
private flushTimer;
|
|
9
9
|
private dirReady;
|
|
10
10
|
constructor();
|
|
11
|
-
private ensureDir;
|
|
12
11
|
append(event: Omit<FirewallEvent, "timestamp">): void;
|
|
13
12
|
private startFlushTimer;
|
|
14
13
|
/**
|
|
15
|
-
* Flush buffer to disk (
|
|
16
|
-
*
|
|
14
|
+
* Flush buffer to disk (append mode — preserves history)
|
|
15
|
+
* Copy-and-replace pattern prevents concurrent flushes from interleaving
|
|
17
16
|
*/
|
|
18
17
|
flush(): void;
|
|
19
18
|
close(): Promise<void>;
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,CAAC;AAQ9B,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,QAAQ,CAAS;;IAMzB,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,CAAC;AAQ9B,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,QAAQ,CAAS;;IAMzB,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,IAAI;IAQrD,OAAO,CAAC,eAAe;IAUvB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAWP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,WAAW,IAAI,MAAM;IAIrB,iBAAiB,IAAI,MAAM;CAG5B"}
|
package/dist/store.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JSONL event storage (async, non-blocking hook)
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { appendFileSync, mkdirSync, existsSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
const FLUSH_INTERVAL_MS = 1000;
|
|
@@ -16,12 +16,6 @@ export class EventStore {
|
|
|
16
16
|
constructor() {
|
|
17
17
|
this.startFlushTimer();
|
|
18
18
|
}
|
|
19
|
-
ensureDir() {
|
|
20
|
-
if (this.dirReady)
|
|
21
|
-
return;
|
|
22
|
-
mkdirSync(STATE_DIR, { recursive: true });
|
|
23
|
-
this.dirReady = true;
|
|
24
|
-
}
|
|
25
19
|
append(event) {
|
|
26
20
|
const fullEvent = {
|
|
27
21
|
...event,
|
|
@@ -38,18 +32,18 @@ export class EventStore {
|
|
|
38
32
|
}
|
|
39
33
|
}
|
|
40
34
|
/**
|
|
41
|
-
* Flush buffer to disk (
|
|
42
|
-
*
|
|
35
|
+
* Flush buffer to disk (append mode — preserves history)
|
|
36
|
+
* Copy-and-replace pattern prevents concurrent flushes from interleaving
|
|
43
37
|
*/
|
|
44
38
|
flush() {
|
|
45
39
|
if (this.buffer.length === 0)
|
|
46
40
|
return;
|
|
47
|
-
// Copy-and-replace: grab current buffer and clear it atomically
|
|
48
41
|
const batch = this.buffer;
|
|
49
42
|
this.buffer = [];
|
|
50
|
-
|
|
43
|
+
if (!existsSync(STATE_DIR))
|
|
44
|
+
mkdirSync(STATE_DIR, { recursive: true });
|
|
51
45
|
const lines = batch.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
52
|
-
|
|
46
|
+
appendFileSync(EVENTS_FILE, lines, "utf-8");
|
|
53
47
|
}
|
|
54
48
|
async close() {
|
|
55
49
|
if (this.flushTimer) {
|
package/dist/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKlC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB;IAC9C,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,SAAS,EAAE,iBAAiB,CAAC;IACpE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AAEpD,MAAM,OAAO,UAAU;IACb,MAAM,GAAoB,EAAE,CAAC;IAC7B,UAAU,GAA0C,IAAI,CAAC;IACzD,QAAQ,GAAG,KAAK,CAAC;IAEzB;QACE,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,KAAuC;QAC5C,MAAM,SAAS,GAAkB;YAC/B,GAAG,KAAK;YACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,iBAAiB,CAAC,CAAC;QAEtB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAErC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAEjB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACpE,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED,WAAW;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iBAAiB;QACf,OAAO,WAAW,CAAC;IACrB,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mapick/cost-firewall",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Mapick Cost Firewall — OpenClaw Plugs",
|
|
6
6
|
"type": "module",
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
},
|
|
29
29
|
"openclaw": {
|
|
30
30
|
"extensions": [
|
|
31
|
-
"./
|
|
31
|
+
"./dist/index.js"
|
|
32
|
+
],
|
|
33
|
+
"providers": [
|
|
34
|
+
"mapick"
|
|
32
35
|
],
|
|
33
|
-
"providers": ["mapick"],
|
|
34
36
|
"compat": {
|
|
35
37
|
"pluginApi": ">=2026.3.24-beta.2",
|
|
36
38
|
"minGatewayVersion": "2026.3.24-beta.2"
|