@clawnitor/plugin 1.0.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 (62) hide show
  1. package/README.md +60 -0
  2. package/dist/config.d.ts +10 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +16 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/event-builder.d.ts +15 -0
  7. package/dist/event-builder.d.ts.map +1 -0
  8. package/dist/event-builder.js +34 -0
  9. package/dist/event-builder.js.map +1 -0
  10. package/dist/hooks/lifecycle.d.ts +18 -0
  11. package/dist/hooks/lifecycle.d.ts.map +1 -0
  12. package/dist/hooks/lifecycle.js +79 -0
  13. package/dist/hooks/lifecycle.js.map +1 -0
  14. package/dist/hooks/llm.d.ts +11 -0
  15. package/dist/hooks/llm.d.ts.map +1 -0
  16. package/dist/hooks/llm.js +35 -0
  17. package/dist/hooks/llm.js.map +1 -0
  18. package/dist/hooks/message.d.ts +14 -0
  19. package/dist/hooks/message.d.ts.map +1 -0
  20. package/dist/hooks/message.js +52 -0
  21. package/dist/hooks/message.js.map +1 -0
  22. package/dist/hooks/tool-call.d.ts +20 -0
  23. package/dist/hooks/tool-call.d.ts.map +1 -0
  24. package/dist/hooks/tool-call.js +89 -0
  25. package/dist/hooks/tool-call.js.map +1 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +105 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/kill-switch/kill-state.d.ts +16 -0
  31. package/dist/kill-switch/kill-state.d.ts.map +1 -0
  32. package/dist/kill-switch/kill-state.js +25 -0
  33. package/dist/kill-switch/kill-state.js.map +1 -0
  34. package/dist/kill-switch/local-failsafe.d.ts +19 -0
  35. package/dist/kill-switch/local-failsafe.d.ts.map +1 -0
  36. package/dist/kill-switch/local-failsafe.js +64 -0
  37. package/dist/kill-switch/local-failsafe.js.map +1 -0
  38. package/dist/redaction.d.ts +3 -0
  39. package/dist/redaction.d.ts.map +1 -0
  40. package/dist/redaction.js +46 -0
  41. package/dist/redaction.js.map +1 -0
  42. package/dist/rule-cache.d.ts +42 -0
  43. package/dist/rule-cache.d.ts.map +1 -0
  44. package/dist/rule-cache.js +138 -0
  45. package/dist/rule-cache.js.map +1 -0
  46. package/dist/severity.d.ts +8 -0
  47. package/dist/severity.d.ts.map +1 -0
  48. package/dist/severity.js +38 -0
  49. package/dist/severity.js.map +1 -0
  50. package/dist/transport/https-sender.d.ts +18 -0
  51. package/dist/transport/https-sender.d.ts.map +1 -0
  52. package/dist/transport/https-sender.js +62 -0
  53. package/dist/transport/https-sender.js.map +1 -0
  54. package/dist/transport/sqlite-cache.d.ts +12 -0
  55. package/dist/transport/sqlite-cache.d.ts.map +1 -0
  56. package/dist/transport/sqlite-cache.js +74 -0
  57. package/dist/transport/sqlite-cache.js.map +1 -0
  58. package/dist/transport/websocket-client.d.ts +19 -0
  59. package/dist/transport/websocket-client.d.ts.map +1 -0
  60. package/dist/transport/websocket-client.js +79 -0
  61. package/dist/transport/websocket-client.js.map +1 -0
  62. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # @clawnitor/plugin
2
+
3
+ OpenClaw plugin for Clawnitor — agent monitoring, alerting, and kill switch.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ openclaw plugins install @clawnitor/plugin
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Add to your `openclaw.json`:
14
+
15
+ ```json
16
+ {
17
+ "plugins": {
18
+ "entries": {
19
+ "clawnitor": {
20
+ "config": {
21
+ "apiKey": "clw_live_your_key_here"
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ ### Options
30
+
31
+ | Option | Default | Description |
32
+ |--------|---------|-------------|
33
+ | `apiKey` | required | Your Clawnitor API key |
34
+ | `backendUrl` | `https://api.clawnitor.io` | Backend URL |
35
+ | `spendLimit` | `100` | Max spend per session ($) before auto-pause |
36
+ | `rateLimit` | `120` | Max tool calls per minute before auto-pause |
37
+ | `toolBlocklist` | `[]` | Tool names to always block |
38
+ | `redactionPatterns` | `[]` | Additional regex patterns for secret redaction |
39
+
40
+ ## What it monitors
41
+
42
+ - Tool calls (before and after execution)
43
+ - LLM requests (input/output, token usage, cost)
44
+ - Messages (sending, sent, received)
45
+ - Session lifecycle (start, end, agent completion)
46
+ - Sub-agent spawning and completion
47
+
48
+ ## Safety features
49
+
50
+ - **Kill switch** — blocks tool calls and messages when agent is paused (server or local)
51
+ - **Spend circuit breaker** — auto-pauses at configurable spend limit
52
+ - **Rate limiter** — auto-pauses at configurable tool call rate
53
+ - **Tool blocklist** — prevents specific tools from ever executing
54
+ - **Secret redaction** — strips API keys, passwords, tokens from logged data
55
+
56
+ ## Privacy
57
+
58
+ Event data streams to the Clawnitor backend for monitoring. Sensitive data (API keys, passwords, tokens) is automatically redacted before transmission. Data sharing for aggregate pattern improvement is opt-in (default OFF).
59
+
60
+ Learn more at https://clawnitor.io
@@ -0,0 +1,10 @@
1
+ export interface PluginConfig {
2
+ apiKey: string;
3
+ backendUrl: string;
4
+ spendLimit: number;
5
+ rateLimit: number;
6
+ toolBlocklist: string[];
7
+ redactionPatterns: string[];
8
+ }
9
+ export declare function parseConfig(raw: Record<string, unknown>): PluginConfig;
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,CActE"}
package/dist/config.js ADDED
@@ -0,0 +1,16 @@
1
+ import { DEFAULT_SPEND_LIMIT, DEFAULT_RATE_LIMIT, } from "@clawnitor/shared";
2
+ export function parseConfig(raw) {
3
+ const apiKey = raw.apiKey;
4
+ if (!apiKey) {
5
+ throw new Error("Clawnitor: apiKey is required. Sign up at https://clawnitor.io");
6
+ }
7
+ return {
8
+ apiKey,
9
+ backendUrl: raw.backendUrl || "https://api.clawnitor.io",
10
+ spendLimit: raw.spendLimit ?? DEFAULT_SPEND_LIMIT,
11
+ rateLimit: raw.rateLimit ?? DEFAULT_RATE_LIMIT,
12
+ toolBlocklist: raw.toolBlocklist ?? [],
13
+ redactionPatterns: raw.redactionPatterns ?? [],
14
+ };
15
+ }
16
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAW3B,MAAM,UAAU,WAAW,CAAC,GAA4B;IACtD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAgB,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO;QACL,MAAM;QACN,UAAU,EAAG,GAAG,CAAC,UAAqB,IAAI,0BAA0B;QACpE,UAAU,EAAG,GAAG,CAAC,UAAqB,IAAI,mBAAmB;QAC7D,SAAS,EAAG,GAAG,CAAC,SAAoB,IAAI,kBAAkB;QAC1D,aAAa,EAAG,GAAG,CAAC,aAA0B,IAAI,EAAE;QACpD,iBAAiB,EAAG,GAAG,CAAC,iBAA8B,IAAI,EAAE;KAC7D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type ClawnitorEvent, type EventType } from "@clawnitor/shared";
2
+ import { type RateTracker } from "./severity.js";
3
+ interface BuildEventParams {
4
+ agentId: string;
5
+ sessionId: string;
6
+ eventType: EventType;
7
+ action: string;
8
+ target: string;
9
+ metadata?: Record<string, unknown>;
10
+ rateTracker?: RateTracker;
11
+ customRedactionPatterns?: string[];
12
+ }
13
+ export declare function buildEvent(params: BuildEventParams): ClawnitorEvent;
14
+ export {};
15
+ //# sourceMappingURL=event-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-builder.d.ts","sourceRoot":"","sources":["../src/event-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAqB,MAAM,mBAAmB,CAAC;AAC1G,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAKjE,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,cAAc,CA6CnE"}
@@ -0,0 +1,34 @@
1
+ import { createEventId } from "@clawnitor/shared";
2
+ import { assignSeverity } from "./severity.js";
3
+ import { redact, DEFAULT_PATTERNS } from "./redaction.js";
4
+ const PLUGIN_VERSION = "0.0.1";
5
+ export function buildEvent(params) {
6
+ const { agentId, sessionId, eventType, action, target, metadata = {}, rateTracker, customRedactionPatterns = [], } = params;
7
+ // Redact sensitive data from raw_snippet
8
+ const patterns = [...DEFAULT_PATTERNS, ...customRedactionPatterns];
9
+ const cleaned = { ...metadata };
10
+ if (typeof cleaned.raw_snippet === "string") {
11
+ cleaned.raw_snippet = redact(cleaned.raw_snippet, patterns);
12
+ // Truncate to 500 chars
13
+ if (cleaned.raw_snippet.length > 500) {
14
+ cleaned.raw_snippet = cleaned.raw_snippet.slice(0, 500);
15
+ }
16
+ }
17
+ const severity = assignSeverity(eventType, cleaned, rateTracker);
18
+ // Redact action and target fields too
19
+ const redactedAction = redact(action, patterns);
20
+ const redactedTarget = redact(target, patterns);
21
+ return {
22
+ agent_id: agentId,
23
+ session_id: sessionId,
24
+ timestamp: new Date().toISOString(),
25
+ event_type: eventType,
26
+ action: redactedAction,
27
+ target: redactedTarget,
28
+ metadata: cleaned,
29
+ severity_hint: severity,
30
+ event_id: createEventId(),
31
+ plugin_version: PLUGIN_VERSION,
32
+ };
33
+ }
34
+ //# sourceMappingURL=event-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-builder.js","sourceRoot":"","sources":["../src/event-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA0D,MAAM,mBAAmB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAoB,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,cAAc,GAAG,OAAO,CAAC;AAa/B,MAAM,UAAU,UAAU,CAAC,MAAwB;IACjD,MAAM,EACJ,OAAO,EACP,SAAS,EACT,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,GAAG,EAAE,EACb,WAAW,EACX,uBAAuB,GAAG,EAAE,GAC7B,GAAG,MAAM,CAAC;IAEX,yCAAyC;IACzC,MAAM,QAAQ,GAAG,CAAC,GAAG,gBAAgB,EAAE,GAAG,uBAAuB,CAAC,CAAC;IACnE,MAAM,OAAO,GAA4B,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzD,IAAI,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC5D,wBAAwB;QACxB,IAAK,OAAO,CAAC,WAAsB,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACjD,OAAO,CAAC,WAAW,GAAI,OAAO,CAAC,WAAsB,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAC7B,SAAS,EACT,OAAO,EACP,WAAW,CACZ,CAAC;IAEF,sCAAsC;IACtC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEhD,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,cAAc;QACtB,MAAM,EAAE,cAAc;QACtB,QAAQ,EAAE,OAAc;QACxB,aAAa,EAAE,QAAQ;QACvB,QAAQ,EAAE,aAAa,EAAE;QACzB,cAAc,EAAE,cAAc;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { HttpsSender } from "../transport/https-sender.js";
2
+ interface LifecycleContext {
3
+ agentId: string;
4
+ sessionId: string;
5
+ sender: HttpsSender;
6
+ redactionPatterns: string[];
7
+ onSessionStart?: (sessionId: string) => void;
8
+ onSessionEnd?: (sessionId: string) => void;
9
+ }
10
+ export declare function createSessionStartHandler(ctx: LifecycleContext): (event: any) => void;
11
+ export declare function createSessionEndHandler(ctx: LifecycleContext): (event: any) => void;
12
+ export declare function createAgentEndHandler(ctx: LifecycleContext): (event: any) => void;
13
+ export declare function createSubagentHandlers(ctx: LifecycleContext): {
14
+ spawning: (event: any) => void;
15
+ ended: (event: any) => void;
16
+ };
17
+ export {};
18
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/hooks/lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,gBAAgB,IACrD,OAAO,GAAG,UAenB;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,IACnD,OAAO,GAAG,UAiBnB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,IACjD,OAAO,GAAG,UAgBnB;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,gBAAgB;sBAEtC,GAAG;mBAYN,GAAG;EAarB"}
@@ -0,0 +1,79 @@
1
+ import { buildEvent } from "../event-builder.js";
2
+ export function createSessionStartHandler(ctx) {
3
+ return (event) => {
4
+ ctx.onSessionStart?.(event.sessionId || ctx.sessionId);
5
+ const clawnitorEvent = buildEvent({
6
+ agentId: ctx.agentId,
7
+ sessionId: event.sessionId || ctx.sessionId,
8
+ eventType: "agent_lifecycle",
9
+ action: "session started",
10
+ target: "session",
11
+ metadata: {},
12
+ customRedactionPatterns: ctx.redactionPatterns,
13
+ });
14
+ ctx.sender.enqueue(clawnitorEvent);
15
+ };
16
+ }
17
+ export function createSessionEndHandler(ctx) {
18
+ return (event) => {
19
+ ctx.onSessionEnd?.(event.sessionId || ctx.sessionId);
20
+ const clawnitorEvent = buildEvent({
21
+ agentId: ctx.agentId,
22
+ sessionId: event.sessionId || ctx.sessionId,
23
+ eventType: "agent_lifecycle",
24
+ action: "session ended",
25
+ target: "session",
26
+ metadata: {
27
+ duration_ms: event.duration,
28
+ },
29
+ customRedactionPatterns: ctx.redactionPatterns,
30
+ });
31
+ ctx.sender.enqueue(clawnitorEvent);
32
+ };
33
+ }
34
+ export function createAgentEndHandler(ctx) {
35
+ return (event) => {
36
+ const clawnitorEvent = buildEvent({
37
+ agentId: ctx.agentId,
38
+ sessionId: ctx.sessionId,
39
+ eventType: "agent_lifecycle",
40
+ action: event.error ? "agent ended with error" : "agent ended",
41
+ target: "agent",
42
+ metadata: {
43
+ duration_ms: event.duration,
44
+ error: event.error?.message,
45
+ },
46
+ customRedactionPatterns: ctx.redactionPatterns,
47
+ });
48
+ ctx.sender.enqueue(clawnitorEvent);
49
+ };
50
+ }
51
+ export function createSubagentHandlers(ctx) {
52
+ return {
53
+ spawning: (event) => {
54
+ const clawnitorEvent = buildEvent({
55
+ agentId: ctx.agentId,
56
+ sessionId: ctx.sessionId,
57
+ eventType: "subagent",
58
+ action: "subagent spawning",
59
+ target: event.subagentId || "unknown",
60
+ metadata: {},
61
+ customRedactionPatterns: ctx.redactionPatterns,
62
+ });
63
+ ctx.sender.enqueue(clawnitorEvent);
64
+ },
65
+ ended: (event) => {
66
+ const clawnitorEvent = buildEvent({
67
+ agentId: ctx.agentId,
68
+ sessionId: ctx.sessionId,
69
+ eventType: "subagent",
70
+ action: "subagent ended",
71
+ target: event.subagentId || "unknown",
72
+ metadata: { duration_ms: event.duration },
73
+ customRedactionPatterns: ctx.redactionPatterns,
74
+ });
75
+ ctx.sender.enqueue(clawnitorEvent);
76
+ },
77
+ };
78
+ }
79
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/hooks/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { HttpsSender } from "../transport/https-sender.js";
2
+ interface LlmContext {
3
+ agentId: string;
4
+ sessionId: string;
5
+ sender: HttpsSender;
6
+ redactionPatterns: string[];
7
+ }
8
+ export declare function createLlmInputHandler(ctx: LlmContext): (event: any) => void;
9
+ export declare function createLlmOutputHandler(ctx: LlmContext): (event: any) => void;
10
+ export {};
11
+ //# sourceMappingURL=llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/hooks/llm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,IAC3C,OAAO,GAAG,UAenB;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,UAAU,IAC5C,OAAO,GAAG,UAgBnB"}
@@ -0,0 +1,35 @@
1
+ import { buildEvent } from "../event-builder.js";
2
+ export function createLlmInputHandler(ctx) {
3
+ return (event) => {
4
+ const clawnitorEvent = buildEvent({
5
+ agentId: ctx.agentId,
6
+ sessionId: ctx.sessionId,
7
+ eventType: "llm_call",
8
+ action: `llm_input: ${event.model || "unknown"}`,
9
+ target: event.provider || "unknown",
10
+ metadata: {
11
+ tool_name: event.model,
12
+ },
13
+ customRedactionPatterns: ctx.redactionPatterns,
14
+ });
15
+ ctx.sender.enqueue(clawnitorEvent);
16
+ };
17
+ }
18
+ export function createLlmOutputHandler(ctx) {
19
+ return (event) => {
20
+ const clawnitorEvent = buildEvent({
21
+ agentId: ctx.agentId,
22
+ sessionId: ctx.sessionId,
23
+ eventType: "llm_call",
24
+ action: `llm_output: ${event.model || "unknown"}`,
25
+ target: event.provider || "unknown",
26
+ metadata: {
27
+ tokens_used: event.usage?.totalTokens,
28
+ cost_usd: event.usage?.cost,
29
+ },
30
+ customRedactionPatterns: ctx.redactionPatterns,
31
+ });
32
+ ctx.sender.enqueue(clawnitorEvent);
33
+ };
34
+ }
35
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/hooks/llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAUjD,MAAM,UAAU,qBAAqB,CAAC,GAAe;IACnD,OAAO,CAAC,KAAU,EAAE,EAAE;QACpB,MAAM,cAAc,GAAG,UAAU,CAAC;YAChC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,UAAU;YACrB,MAAM,EAAE,cAAc,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE;YAChD,MAAM,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;YACnC,QAAQ,EAAE;gBACR,SAAS,EAAE,KAAK,CAAC,KAAK;aACvB;YACD,uBAAuB,EAAE,GAAG,CAAC,iBAAiB;SAC/C,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAe;IACpD,OAAO,CAAC,KAAU,EAAE,EAAE;QACpB,MAAM,cAAc,GAAG,UAAU,CAAC;YAChC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,UAAU;YACrB,MAAM,EAAE,eAAe,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE;YACjD,MAAM,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;YACnC,QAAQ,EAAE;gBACR,WAAW,EAAE,KAAK,CAAC,KAAK,EAAE,WAAW;gBACrC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI;aAC5B;YACD,uBAAuB,EAAE,GAAG,CAAC,iBAAiB;SAC/C,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { HttpsSender } from "../transport/https-sender.js";
2
+ interface MessageContext {
3
+ agentId: string;
4
+ sessionId: string;
5
+ sender: HttpsSender;
6
+ redactionPatterns: string[];
7
+ }
8
+ export declare function createMessageSendingHandler(ctx: MessageContext): (event: any) => {
9
+ cancel: boolean;
10
+ } | undefined;
11
+ export declare function createMessageSentHandler(ctx: MessageContext): (event: any) => void;
12
+ export declare function createMessageReceivedHandler(ctx: MessageContext): (event: any) => void;
13
+ export {};
14
+ //# sourceMappingURL=message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/hooks/message.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAGhE,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,cAAc,IACrD,OAAO,GAAG;;cAsBnB;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,cAAc,IAClD,OAAO,GAAG,UAanB;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,cAAc,IACtD,OAAO,GAAG,UAanB"}
@@ -0,0 +1,52 @@
1
+ import { buildEvent } from "../event-builder.js";
2
+ import { killState } from "../kill-switch/kill-state.js";
3
+ export function createMessageSendingHandler(ctx) {
4
+ return (event) => {
5
+ const clawnitorEvent = buildEvent({
6
+ agentId: ctx.agentId,
7
+ sessionId: ctx.sessionId,
8
+ eventType: "message_sent",
9
+ action: `sending message`,
10
+ target: event.channel || "unknown",
11
+ metadata: {
12
+ raw_snippet: event.text ? String(event.text).slice(0, 500) : undefined,
13
+ },
14
+ customRedactionPatterns: ctx.redactionPatterns,
15
+ });
16
+ ctx.sender.enqueue(clawnitorEvent);
17
+ // Block outbound messages when killed
18
+ if (killState.isKilled()) {
19
+ return { cancel: true };
20
+ }
21
+ return undefined;
22
+ };
23
+ }
24
+ export function createMessageSentHandler(ctx) {
25
+ return (event) => {
26
+ const clawnitorEvent = buildEvent({
27
+ agentId: ctx.agentId,
28
+ sessionId: ctx.sessionId,
29
+ eventType: "message_sent",
30
+ action: `message sent`,
31
+ target: event.channel || "unknown",
32
+ metadata: {},
33
+ customRedactionPatterns: ctx.redactionPatterns,
34
+ });
35
+ ctx.sender.enqueue(clawnitorEvent);
36
+ };
37
+ }
38
+ export function createMessageReceivedHandler(ctx) {
39
+ return (event) => {
40
+ const clawnitorEvent = buildEvent({
41
+ agentId: ctx.agentId,
42
+ sessionId: ctx.sessionId,
43
+ eventType: "message_received",
44
+ action: `message received`,
45
+ target: event.channel || "unknown",
46
+ metadata: {},
47
+ customRedactionPatterns: ctx.redactionPatterns,
48
+ });
49
+ ctx.sender.enqueue(clawnitorEvent);
50
+ };
51
+ }
52
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/hooks/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AASzD,MAAM,UAAU,2BAA2B,CAAC,GAAmB;IAC7D,OAAO,CAAC,KAAU,EAAE,EAAE;QACpB,MAAM,cAAc,GAAG,UAAU,CAAC;YAChC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,cAAc;YACzB,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,KAAK,CAAC,OAAO,IAAI,SAAS;YAClC,QAAQ,EAAE;gBACR,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;aACvE;YACD,uBAAuB,EAAE,GAAG,CAAC,iBAAiB;SAC/C,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEnC,sCAAsC;QACtC,IAAI,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;YACzB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC1B,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAmB;IAC1D,OAAO,CAAC,KAAU,EAAE,EAAE;QACpB,MAAM,cAAc,GAAG,UAAU,CAAC;YAChC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,cAAc;YACzB,MAAM,EAAE,cAAc;YACtB,MAAM,EAAE,KAAK,CAAC,OAAO,IAAI,SAAS;YAClC,QAAQ,EAAE,EAAE;YACZ,uBAAuB,EAAE,GAAG,CAAC,iBAAiB;SAC/C,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,GAAmB;IAC9D,OAAO,CAAC,KAAU,EAAE,EAAE;QACpB,MAAM,cAAc,GAAG,UAAU,CAAC;YAChC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,kBAAkB;YAC7B,MAAM,EAAE,kBAAkB;YAC1B,MAAM,EAAE,KAAK,CAAC,OAAO,IAAI,SAAS;YAClC,QAAQ,EAAE,EAAE;YACZ,uBAAuB,EAAE,GAAG,CAAC,iBAAiB;SAC/C,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { HttpsSender } from "../transport/https-sender.js";
2
+ import type { RateTracker } from "../severity.js";
3
+ import type { LocalFailsafe } from "../kill-switch/local-failsafe.js";
4
+ import type { RuleCache } from "../rule-cache.js";
5
+ interface ToolCallContext {
6
+ agentId: string;
7
+ sessionId: string;
8
+ sender: HttpsSender;
9
+ rateTracker: RateTracker;
10
+ redactionPatterns: string[];
11
+ failsafe: LocalFailsafe;
12
+ ruleCache: RuleCache;
13
+ }
14
+ export declare function createBeforeToolCallHandler(ctx: ToolCallContext): (event: any) => {
15
+ block: boolean;
16
+ blockReason: string | undefined;
17
+ } | undefined;
18
+ export declare function createAfterToolCallHandler(ctx: ToolCallContext): (event: any) => void;
19
+ export {};
20
+ //# sourceMappingURL=tool-call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-call.d.ts","sourceRoot":"","sources":["../../src/hooks/tool-call.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,eAAe,IACtD,OAAO,GAAG;;;cA+DnB;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,eAAe,IACrD,OAAO,GAAG,UA+BnB"}
@@ -0,0 +1,89 @@
1
+ import { buildEvent } from "../event-builder.js";
2
+ import { killState } from "../kill-switch/kill-state.js";
3
+ export function createBeforeToolCallHandler(ctx) {
4
+ return (event) => {
5
+ ctx.rateTracker.record();
6
+ ctx.failsafe.recordToolCall();
7
+ // Record event in rule cache for time-window based rules
8
+ ctx.ruleCache.recordEvent({
9
+ timestamp: Date.now(),
10
+ toolName: event.toolName,
11
+ eventType: "tool_use",
12
+ costUsd: event.cost,
13
+ action: event.toolName,
14
+ target: event.toolName,
15
+ });
16
+ const clawnitorEvent = buildEvent({
17
+ agentId: ctx.agentId,
18
+ sessionId: ctx.sessionId,
19
+ eventType: "tool_use",
20
+ action: `before: ${event.toolName || "unknown"}`,
21
+ target: event.toolName || "unknown",
22
+ metadata: {
23
+ tool_name: event.toolName,
24
+ ...(event.params ? { raw_snippet: JSON.stringify(event.params).slice(0, 500) } : {}),
25
+ },
26
+ rateTracker: ctx.rateTracker,
27
+ customRedactionPatterns: ctx.redactionPatterns,
28
+ });
29
+ ctx.sender.enqueue(clawnitorEvent);
30
+ // 1. Check kill state (server-triggered)
31
+ if (killState.isKilled()) {
32
+ return {
33
+ block: true,
34
+ blockReason: `Clawnitor: agent paused — ${killState.getReason() || "unknown reason"}`,
35
+ };
36
+ }
37
+ // 2. Check local failsafe (spend/rate/blocklist)
38
+ const failsafeResult = ctx.failsafe.check(event.toolName || "");
39
+ if (failsafeResult.block) {
40
+ killState.setKilled(failsafeResult.reason);
41
+ return {
42
+ block: true,
43
+ blockReason: failsafeResult.reason,
44
+ };
45
+ }
46
+ // 3. Check cached server rules locally (PRE-ACTION for pattern rules)
47
+ const ruleResult = ctx.ruleCache.checkBeforeToolCall(event.toolName || "", event.params);
48
+ if (ruleResult.blocked) {
49
+ killState.setKilled(ruleResult.reason || "Rule triggered");
50
+ return {
51
+ block: true,
52
+ blockReason: ruleResult.reason,
53
+ };
54
+ }
55
+ return undefined;
56
+ };
57
+ }
58
+ export function createAfterToolCallHandler(ctx) {
59
+ return (event) => {
60
+ // Track spend for failsafe and rule cache
61
+ if (typeof event.cost === "number") {
62
+ ctx.failsafe.addSpend(event.cost);
63
+ ctx.ruleCache.recordEvent({
64
+ timestamp: Date.now(),
65
+ toolName: event.toolName,
66
+ eventType: "tool_use",
67
+ costUsd: event.cost,
68
+ });
69
+ }
70
+ const clawnitorEvent = buildEvent({
71
+ agentId: ctx.agentId,
72
+ sessionId: ctx.sessionId,
73
+ eventType: "tool_use",
74
+ action: `after: ${event.toolName || "unknown"}`,
75
+ target: event.toolName || "unknown",
76
+ metadata: {
77
+ tool_name: event.toolName,
78
+ duration_ms: event.duration,
79
+ error: event.error?.message,
80
+ cost_usd: event.cost,
81
+ raw_snippet: event.result ? String(event.result).slice(0, 500) : undefined,
82
+ },
83
+ rateTracker: ctx.rateTracker,
84
+ customRedactionPatterns: ctx.redactionPatterns,
85
+ });
86
+ ctx.sender.enqueue(clawnitorEvent);
87
+ };
88
+ }
89
+ //# sourceMappingURL=tool-call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-call.js","sourceRoot":"","sources":["../../src/hooks/tool-call.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function register(api: any): void;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAyBA,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QA0GxC"}
package/dist/index.js ADDED
@@ -0,0 +1,105 @@
1
+ import { parseConfig } from "./config.js";
2
+ import { HttpsSender } from "./transport/https-sender.js";
3
+ import { SqliteCache } from "./transport/sqlite-cache.js";
4
+ import { WebSocketClient } from "./transport/websocket-client.js";
5
+ import { createRateTracker } from "./severity.js";
6
+ import { killState } from "./kill-switch/kill-state.js";
7
+ import { LocalFailsafe } from "./kill-switch/local-failsafe.js";
8
+ import { RuleCache } from "./rule-cache.js";
9
+ import { createBeforeToolCallHandler, createAfterToolCallHandler, } from "./hooks/tool-call.js";
10
+ import { createLlmInputHandler, createLlmOutputHandler } from "./hooks/llm.js";
11
+ import { createMessageSendingHandler, createMessageSentHandler, createMessageReceivedHandler, } from "./hooks/message.js";
12
+ import { createSessionStartHandler, createSessionEndHandler, createAgentEndHandler, createSubagentHandlers, } from "./hooks/lifecycle.js";
13
+ export default function register(api) {
14
+ const rawConfig = api.config || {};
15
+ const config = parseConfig(rawConfig);
16
+ const rateTracker = createRateTracker();
17
+ const failsafe = new LocalFailsafe(config);
18
+ const ruleCache = new RuleCache(config);
19
+ // Initialize SQLite cache for offline resilience
20
+ const cache = new SqliteCache();
21
+ // Initialize HTTPS sender
22
+ const sender = new HttpsSender(config, {
23
+ onKillState: (killed, reason) => {
24
+ // HTTPS fallback for kill state
25
+ if (killed && !killState.isKilled()) {
26
+ killState.setKilled(reason || "Killed by server (HTTPS fallback)");
27
+ }
28
+ else if (!killed && killState.isKilled()) {
29
+ killState.clearKilled();
30
+ }
31
+ },
32
+ onFlushFail: (events) => {
33
+ cache.cache(events);
34
+ },
35
+ });
36
+ sender.start();
37
+ // Initialize WebSocket client for real-time kill signals
38
+ const wsClient = new WebSocketClient(config, {
39
+ onKill: (reason, ruleId) => {
40
+ killState.setKilled(reason);
41
+ },
42
+ onUnkill: () => {
43
+ killState.clearKilled();
44
+ },
45
+ });
46
+ wsClient.start();
47
+ ruleCache.start();
48
+ // Periodically flush cached events
49
+ const cacheFlushInterval = setInterval(() => {
50
+ const cached = cache.flush(50);
51
+ if (cached.length > 0) {
52
+ for (const event of cached) {
53
+ sender.enqueue(event);
54
+ }
55
+ }
56
+ }, 30_000);
57
+ // Shared context for all hooks
58
+ let currentSessionId = "default";
59
+ const agentId = rawConfig.agentId || "unknown";
60
+ const ctx = {
61
+ get agentId() {
62
+ return agentId;
63
+ },
64
+ get sessionId() {
65
+ return currentSessionId;
66
+ },
67
+ sender,
68
+ rateTracker,
69
+ redactionPatterns: config.redactionPatterns,
70
+ failsafe,
71
+ ruleCache,
72
+ };
73
+ // Register hooks
74
+ api.on("before_tool_call", createBeforeToolCallHandler(ctx), {
75
+ priority: 10,
76
+ });
77
+ api.on("after_tool_call", createAfterToolCallHandler(ctx), { priority: 10 });
78
+ api.on("llm_input", createLlmInputHandler(ctx), { priority: 10 });
79
+ api.on("llm_output", createLlmOutputHandler(ctx), { priority: 10 });
80
+ api.on("message_sending", createMessageSendingHandler(ctx), {
81
+ priority: 10,
82
+ });
83
+ api.on("message_sent", createMessageSentHandler(ctx), { priority: 10 });
84
+ api.on("message_received", createMessageReceivedHandler(ctx), {
85
+ priority: 10,
86
+ });
87
+ api.on("session_start", createSessionStartHandler({
88
+ ...ctx,
89
+ onSessionStart: (sid) => {
90
+ currentSessionId = sid;
91
+ failsafe.resetSession();
92
+ },
93
+ }), { priority: 10 });
94
+ api.on("session_end", createSessionEndHandler({
95
+ ...ctx,
96
+ onSessionEnd: () => {
97
+ currentSessionId = "default";
98
+ },
99
+ }), { priority: 10 });
100
+ api.on("agent_end", createAgentEndHandler(ctx), { priority: 10 });
101
+ const subagent = createSubagentHandlers(ctx);
102
+ api.on("subagent_spawning", subagent.spawning, { priority: 10 });
103
+ api.on("subagent_ended", subagent.ended, { priority: 10 });
104
+ }
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}