clawatch 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.
- package/LICENSE +21 -0
- package/README.md +75 -0
- package/dist/api.d.ts +11 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +77 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +230 -0
- package/dist/cli.js.map +1 -0
- package/dist/collector.d.ts +4 -0
- package/dist/collector.d.ts.map +1 -0
- package/dist/collector.js +249 -0
- package/dist/collector.js.map +1 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +81 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +25 -0
- package/dist/daemon.js.map +1 -0
- package/dist/parser.d.ts +39 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +107 -0
- package/dist/parser.js.map +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GENWAY AI
|
|
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,75 @@
|
|
|
1
|
+
# clawatch
|
|
2
|
+
|
|
3
|
+
> Observability & monitoring for AI agents. Datadog for your AI team.
|
|
4
|
+
|
|
5
|
+
**ClaWatch** tracks your [OpenClaw](https://openclaw.ai) agents in real-time — costs, tokens, sessions, errors — and alerts you when things go wrong.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g clawatch
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Detect agents and configure
|
|
17
|
+
clawatch init
|
|
18
|
+
|
|
19
|
+
# Start monitoring daemon
|
|
20
|
+
clawatch start
|
|
21
|
+
|
|
22
|
+
# Check status
|
|
23
|
+
clawatch status
|
|
24
|
+
|
|
25
|
+
# View logs
|
|
26
|
+
clawatch logs
|
|
27
|
+
|
|
28
|
+
# Stop monitoring
|
|
29
|
+
clawatch stop
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## What It Monitors
|
|
33
|
+
|
|
34
|
+
- **Costs** — Per-agent, per-session, per-model cost tracking (USD)
|
|
35
|
+
- **Tokens** — Input, output, cache read/write breakdown
|
|
36
|
+
- **Sessions** — Active sessions with human-readable titles
|
|
37
|
+
- **Errors** — Tool failures, stuck agents, error spikes
|
|
38
|
+
- **Heartbeats** — Agent liveness detection
|
|
39
|
+
|
|
40
|
+
## How It Works
|
|
41
|
+
|
|
42
|
+
ClaWatch runs a lightweight daemon that watches your `~/.openclaw` directory for new session data. It parses JSONL session files in real-time and reports metrics to the ClaWatch backend.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
~/.openclaw/agents/*/sessions/*.jsonl → clawatch daemon → ClaWatch API → Dashboard + Alerts
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
Config is stored at `~/.clawatch/config.json`:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"backendUrl": "http://localhost:3001",
|
|
55
|
+
"openclawDir": "~/.openclaw",
|
|
56
|
+
"agents": ["anas", "dor", "ofek"]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Dashboard
|
|
61
|
+
|
|
62
|
+
View your agents at [clawatch.dev](https://clawatch.dev) or run the dashboard locally.
|
|
63
|
+
|
|
64
|
+
## Alerts
|
|
65
|
+
|
|
66
|
+
Get notified via Telegram when:
|
|
67
|
+
- An agent gets stuck (no heartbeat for 5+ minutes)
|
|
68
|
+
- Error rate spikes
|
|
69
|
+
- Cost exceeds threshold
|
|
70
|
+
|
|
71
|
+
More channels coming: Slack, Discord, email, PagerDuty.
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT — [GENWAY AI](https://genway.ai)
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface AgentEvent {
|
|
2
|
+
agentId: string;
|
|
3
|
+
agentName: string;
|
|
4
|
+
host: string;
|
|
5
|
+
type: 'heartbeat' | 'cost' | 'status_change' | 'error';
|
|
6
|
+
data?: Record<string, unknown>;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function postEvent(backendUrl: string, event: AgentEvent): Promise<void>;
|
|
10
|
+
export declare function postEvents(backendUrl: string, events: AgentEvent[]): Promise<void[]>;
|
|
11
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC9E;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAEpF"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.postEvent = postEvent;
|
|
37
|
+
exports.postEvents = postEvents;
|
|
38
|
+
const http = __importStar(require("http"));
|
|
39
|
+
const https = __importStar(require("https"));
|
|
40
|
+
const url_1 = require("url");
|
|
41
|
+
function postEvent(backendUrl, event) {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
const url = new url_1.URL('/api/events', backendUrl);
|
|
44
|
+
const body = JSON.stringify(event);
|
|
45
|
+
const mod = url.protocol === 'https:' ? https : http;
|
|
46
|
+
const req = mod.request(url, {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: {
|
|
49
|
+
'Content-Type': 'application/json',
|
|
50
|
+
'Content-Length': Buffer.byteLength(body),
|
|
51
|
+
},
|
|
52
|
+
timeout: 10000,
|
|
53
|
+
}, (res) => {
|
|
54
|
+
let data = '';
|
|
55
|
+
res.on('data', (chunk) => (data += chunk));
|
|
56
|
+
res.on('end', () => {
|
|
57
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
58
|
+
resolve();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
reject(new Error(`HTTP ${res.statusCode}: ${data}`));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
req.on('error', reject);
|
|
66
|
+
req.on('timeout', () => {
|
|
67
|
+
req.destroy();
|
|
68
|
+
reject(new Error('Request timeout'));
|
|
69
|
+
});
|
|
70
|
+
req.write(body);
|
|
71
|
+
req.end();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function postEvents(backendUrl, events) {
|
|
75
|
+
return Promise.all(events.map((e) => postEvent(backendUrl, e)));
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,8BAqCC;AAED,gCAEC;AAtDD,2CAA6B;AAC7B,6CAA+B;AAC/B,6BAA0B;AAW1B,SAAgB,SAAS,CAAC,UAAkB,EAAE,KAAiB;IAC7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,IAAI,SAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAErD,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CACrB,GAAG,EACH;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;aAC1C;YACD,OAAO,EAAE,KAAK;SACf,EACD,CAAC,GAAG,EAAE,EAAE;YACN,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;oBACpE,OAAO,EAAE,CAAC;gBACZ,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CACF,CAAC;QAEF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,UAAU,CAAC,UAAkB,EAAE,MAAoB;IACjE,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const commander_1 = require("commander");
|
|
38
|
+
const chalk = require("chalk");
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const child_process_1 = require("child_process");
|
|
43
|
+
const config_1 = require("./config");
|
|
44
|
+
const program = new commander_1.Command();
|
|
45
|
+
program
|
|
46
|
+
.name('clawatch')
|
|
47
|
+
.description('ClaWatch CLI - Monitor OpenClaw agents')
|
|
48
|
+
.version('1.0.0');
|
|
49
|
+
program
|
|
50
|
+
.command('init')
|
|
51
|
+
.description('Initialize ClaWatch configuration')
|
|
52
|
+
.option('--backend <url>', 'Backend URL', 'http://localhost:3001')
|
|
53
|
+
.action((opts) => {
|
|
54
|
+
const openclawDir = path.join(os.homedir(), '.openclaw');
|
|
55
|
+
if (!fs.existsSync(openclawDir)) {
|
|
56
|
+
console.log(chalk.red(`OpenClaw directory not found: ${openclawDir}`));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const agentsDir = path.join(openclawDir, 'agents');
|
|
60
|
+
const agents = fs.existsSync(agentsDir)
|
|
61
|
+
? fs.readdirSync(agentsDir).filter((name) => {
|
|
62
|
+
const sessionsDir = path.join(agentsDir, name, 'sessions');
|
|
63
|
+
return fs.existsSync(sessionsDir);
|
|
64
|
+
})
|
|
65
|
+
: [];
|
|
66
|
+
const config = {
|
|
67
|
+
openclawDir,
|
|
68
|
+
backendUrl: opts.backend,
|
|
69
|
+
apiKey: '',
|
|
70
|
+
scanIntervalMs: 60000,
|
|
71
|
+
};
|
|
72
|
+
(0, config_1.saveConfig)(config);
|
|
73
|
+
console.log(chalk.green('ClaWatch initialized!'));
|
|
74
|
+
console.log(` Config: ${config_1.paths.config}`);
|
|
75
|
+
console.log(` OpenClaw: ${openclawDir}`);
|
|
76
|
+
console.log(` Backend: ${config.backendUrl}`);
|
|
77
|
+
console.log(` Agents found: ${agents.length} (${agents.join(', ')})`);
|
|
78
|
+
});
|
|
79
|
+
program
|
|
80
|
+
.command('start')
|
|
81
|
+
.description('Start the ClaWatch daemon')
|
|
82
|
+
.action(() => {
|
|
83
|
+
(0, config_1.ensureDir)();
|
|
84
|
+
if (!(0, config_1.configExists)()) {
|
|
85
|
+
console.log(chalk.red('Not initialized. Run: clawatch init'));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
// Check if already running
|
|
89
|
+
if (fs.existsSync(config_1.paths.pid)) {
|
|
90
|
+
const pid = parseInt(fs.readFileSync(config_1.paths.pid, 'utf-8').trim(), 10);
|
|
91
|
+
try {
|
|
92
|
+
process.kill(pid, 0);
|
|
93
|
+
console.log(chalk.yellow(`Daemon already running (PID: ${pid})`));
|
|
94
|
+
process.exit(0);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// PID stale, remove it
|
|
98
|
+
fs.unlinkSync(config_1.paths.pid);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const daemonPath = path.join(__dirname, 'daemon.js');
|
|
102
|
+
const child = (0, child_process_1.fork)(daemonPath, [], {
|
|
103
|
+
detached: true,
|
|
104
|
+
stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
|
|
105
|
+
});
|
|
106
|
+
if (child.pid) {
|
|
107
|
+
fs.writeFileSync(config_1.paths.pid, String(child.pid));
|
|
108
|
+
child.unref();
|
|
109
|
+
child.disconnect();
|
|
110
|
+
console.log(chalk.green(`Daemon started (PID: ${child.pid})`));
|
|
111
|
+
console.log(` Logs: ${config_1.paths.log}`);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.log(chalk.red('Failed to start daemon'));
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
program
|
|
119
|
+
.command('stop')
|
|
120
|
+
.description('Stop the ClaWatch daemon')
|
|
121
|
+
.action(() => {
|
|
122
|
+
if (!fs.existsSync(config_1.paths.pid)) {
|
|
123
|
+
console.log(chalk.yellow('No daemon running'));
|
|
124
|
+
process.exit(0);
|
|
125
|
+
}
|
|
126
|
+
const pid = parseInt(fs.readFileSync(config_1.paths.pid, 'utf-8').trim(), 10);
|
|
127
|
+
try {
|
|
128
|
+
process.kill(pid, 'SIGTERM');
|
|
129
|
+
fs.unlinkSync(config_1.paths.pid);
|
|
130
|
+
console.log(chalk.green(`Daemon stopped (PID: ${pid})`));
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
fs.unlinkSync(config_1.paths.pid);
|
|
134
|
+
console.log(chalk.yellow('Daemon was not running (stale PID removed)'));
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
program
|
|
138
|
+
.command('status')
|
|
139
|
+
.description('Show ClaWatch status')
|
|
140
|
+
.action(() => {
|
|
141
|
+
if (!(0, config_1.configExists)()) {
|
|
142
|
+
console.log(chalk.red('Not initialized. Run: clawatch init'));
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
const config = (0, config_1.loadConfig)();
|
|
146
|
+
// Daemon status
|
|
147
|
+
let daemonRunning = false;
|
|
148
|
+
let daemonPid = 0;
|
|
149
|
+
if (fs.existsSync(config_1.paths.pid)) {
|
|
150
|
+
daemonPid = parseInt(fs.readFileSync(config_1.paths.pid, 'utf-8').trim(), 10);
|
|
151
|
+
try {
|
|
152
|
+
process.kill(daemonPid, 0);
|
|
153
|
+
daemonRunning = true;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
daemonRunning = false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Agent stats
|
|
160
|
+
const agentsDir = path.join(config.openclawDir, 'agents');
|
|
161
|
+
let agentCount = 0;
|
|
162
|
+
let sessionCount = 0;
|
|
163
|
+
let latestEvent = '';
|
|
164
|
+
if (fs.existsSync(agentsDir)) {
|
|
165
|
+
const agents = fs.readdirSync(agentsDir).filter((name) => {
|
|
166
|
+
return fs.existsSync(path.join(agentsDir, name, 'sessions'));
|
|
167
|
+
});
|
|
168
|
+
agentCount = agents.length;
|
|
169
|
+
for (const agent of agents) {
|
|
170
|
+
const sessionsDir = path.join(agentsDir, agent, 'sessions');
|
|
171
|
+
const files = fs.readdirSync(sessionsDir).filter((f) => f.endsWith('.jsonl'));
|
|
172
|
+
sessionCount += files.length;
|
|
173
|
+
for (const file of files) {
|
|
174
|
+
const stat = fs.statSync(path.join(sessionsDir, file));
|
|
175
|
+
const mtime = stat.mtime.toISOString();
|
|
176
|
+
if (mtime > latestEvent)
|
|
177
|
+
latestEvent = mtime;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
console.log(chalk.bold('ClaWatch Status'));
|
|
182
|
+
console.log('─'.repeat(40));
|
|
183
|
+
console.log(` Daemon: ${daemonRunning ? chalk.green(`running (PID: ${daemonPid})`) : chalk.red('stopped')}`);
|
|
184
|
+
console.log(` Backend: ${config.backendUrl}`);
|
|
185
|
+
console.log(` Agents: ${agentCount}`);
|
|
186
|
+
console.log(` Sessions: ${sessionCount}`);
|
|
187
|
+
console.log(` Last event: ${latestEvent || 'none'}`);
|
|
188
|
+
// Check backend connectivity
|
|
189
|
+
const http = require('http');
|
|
190
|
+
const url = new (require('url').URL)('/api/events', config.backendUrl);
|
|
191
|
+
let replied = false;
|
|
192
|
+
const req = http.get(url, { timeout: 3000 }, (res) => {
|
|
193
|
+
if (!replied) {
|
|
194
|
+
replied = true;
|
|
195
|
+
const ok = res.statusCode && res.statusCode < 500;
|
|
196
|
+
console.log(` Connection: ${ok ? chalk.green('ok') : chalk.yellow(`HTTP ${res.statusCode}`)}`);
|
|
197
|
+
}
|
|
198
|
+
res.resume();
|
|
199
|
+
});
|
|
200
|
+
req.on('error', () => {
|
|
201
|
+
if (!replied) {
|
|
202
|
+
replied = true;
|
|
203
|
+
console.log(` Connection: ${chalk.red('unreachable')}`);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
req.on('timeout', () => {
|
|
207
|
+
if (!replied) {
|
|
208
|
+
replied = true;
|
|
209
|
+
req.destroy();
|
|
210
|
+
console.log(` Connection: ${chalk.red('timeout')}`);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
program
|
|
215
|
+
.command('logs')
|
|
216
|
+
.description('Tail daemon logs')
|
|
217
|
+
.option('-n <lines>', 'Number of lines', '50')
|
|
218
|
+
.action((opts) => {
|
|
219
|
+
if (!fs.existsSync(config_1.paths.log)) {
|
|
220
|
+
console.log(chalk.yellow('No log file yet'));
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
const content = fs.readFileSync(config_1.paths.log, 'utf-8');
|
|
224
|
+
const lines = content.trim().split('\n');
|
|
225
|
+
const n = parseInt(opts.n || opts.N || '50', 10);
|
|
226
|
+
const tail = lines.slice(-n);
|
|
227
|
+
console.log(tail.join('\n'));
|
|
228
|
+
});
|
|
229
|
+
program.parse();
|
|
230
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAS,MAAM,UAAU,CAAC;AAqNjD,wBAAsB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE;AAED,wBAAgB,aAAa,IAAI,IAAI,CAcpC"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startCollector = startCollector;
|
|
37
|
+
exports.stopCollector = stopCollector;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const chokidar = __importStar(require("chokidar"));
|
|
41
|
+
const config_1 = require("./config");
|
|
42
|
+
const api_1 = require("./api");
|
|
43
|
+
const parser_1 = require("./parser");
|
|
44
|
+
let offsets = {};
|
|
45
|
+
let config;
|
|
46
|
+
let watcher = null;
|
|
47
|
+
let gatewayWatcher = null;
|
|
48
|
+
let heartbeatInterval = null;
|
|
49
|
+
let activeAgents = new Set();
|
|
50
|
+
function log(msg) {
|
|
51
|
+
const line = `[${new Date().toISOString()}] ${msg}\n`;
|
|
52
|
+
fs.appendFileSync(config_1.paths.log, line);
|
|
53
|
+
}
|
|
54
|
+
function loadOffsets() {
|
|
55
|
+
if (fs.existsSync(config_1.paths.offsets)) {
|
|
56
|
+
try {
|
|
57
|
+
offsets = JSON.parse(fs.readFileSync(config_1.paths.offsets, 'utf-8'));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
offsets = {};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function saveOffsets() {
|
|
65
|
+
fs.writeFileSync(config_1.paths.offsets, JSON.stringify(offsets, null, 2));
|
|
66
|
+
}
|
|
67
|
+
function extractAgentId(filePath) {
|
|
68
|
+
// Path: .../agents/<agentId>/sessions/<file>.jsonl
|
|
69
|
+
const parts = filePath.split(path.sep);
|
|
70
|
+
const agentsIdx = parts.indexOf('agents');
|
|
71
|
+
if (agentsIdx >= 0 && agentsIdx + 1 < parts.length) {
|
|
72
|
+
return parts[agentsIdx + 1];
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
async function sendEvent(event) {
|
|
77
|
+
try {
|
|
78
|
+
await (0, api_1.postEvent)(config.backendUrl, event);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
82
|
+
log(`Failed to send event: ${msg}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function processLines(lines, agentId) {
|
|
86
|
+
for (const line of lines) {
|
|
87
|
+
const event = (0, parser_1.parseLine)(line);
|
|
88
|
+
if (!event)
|
|
89
|
+
continue;
|
|
90
|
+
const apiEvents = (0, parser_1.mapEventToApiEvents)(event, agentId);
|
|
91
|
+
for (const apiEvent of apiEvents) {
|
|
92
|
+
await sendEvent(apiEvent);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function readNewLines(filePath) {
|
|
97
|
+
const agentId = extractAgentId(filePath);
|
|
98
|
+
if (!agentId)
|
|
99
|
+
return;
|
|
100
|
+
activeAgents.add(agentId);
|
|
101
|
+
let stat;
|
|
102
|
+
try {
|
|
103
|
+
stat = fs.statSync(filePath);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const currentOffset = offsets[filePath] || 0;
|
|
109
|
+
if (stat.size <= currentOffset)
|
|
110
|
+
return;
|
|
111
|
+
const fd = fs.openSync(filePath, 'r');
|
|
112
|
+
const buffer = Buffer.alloc(stat.size - currentOffset);
|
|
113
|
+
fs.readSync(fd, buffer, 0, buffer.length, currentOffset);
|
|
114
|
+
fs.closeSync(fd);
|
|
115
|
+
const content = buffer.toString('utf-8');
|
|
116
|
+
const lines = content.split('\n').filter((l) => l.trim());
|
|
117
|
+
if (lines.length > 0) {
|
|
118
|
+
log(`Processing ${lines.length} new lines from ${path.basename(filePath)} (agent: ${agentId})`);
|
|
119
|
+
await processLines(lines, agentId);
|
|
120
|
+
}
|
|
121
|
+
offsets[filePath] = stat.size;
|
|
122
|
+
saveOffsets();
|
|
123
|
+
}
|
|
124
|
+
async function initialScan() {
|
|
125
|
+
const agentsDir = path.join(config.openclawDir, 'agents');
|
|
126
|
+
if (!fs.existsSync(agentsDir)) {
|
|
127
|
+
log(`Agents directory not found: ${agentsDir}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const agents = fs.readdirSync(agentsDir).filter((name) => {
|
|
131
|
+
const sessionsDir = path.join(agentsDir, name, 'sessions');
|
|
132
|
+
return fs.existsSync(sessionsDir) && fs.statSync(path.join(agentsDir, name)).isDirectory();
|
|
133
|
+
});
|
|
134
|
+
log(`Found ${agents.length} agents: ${agents.join(', ')}`);
|
|
135
|
+
for (const agentId of agents) {
|
|
136
|
+
activeAgents.add(agentId);
|
|
137
|
+
const sessionsDir = path.join(agentsDir, agentId, 'sessions');
|
|
138
|
+
const files = fs.readdirSync(sessionsDir).filter((f) => f.endsWith('.jsonl'));
|
|
139
|
+
for (const file of files) {
|
|
140
|
+
const filePath = path.join(sessionsDir, file);
|
|
141
|
+
await readNewLines(filePath);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
log(`Initial scan complete. ${activeAgents.size} agents, offsets tracked for ${Object.keys(offsets).length} files`);
|
|
145
|
+
}
|
|
146
|
+
function startFileWatcher() {
|
|
147
|
+
const pattern = path.join(config.openclawDir, 'agents', '*', 'sessions', '*.jsonl');
|
|
148
|
+
log(`Watching: ${pattern}`);
|
|
149
|
+
watcher = chokidar.watch(pattern, {
|
|
150
|
+
persistent: true,
|
|
151
|
+
ignoreInitial: true,
|
|
152
|
+
awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 },
|
|
153
|
+
});
|
|
154
|
+
watcher.on('add', async (filePath) => {
|
|
155
|
+
log(`New file detected: ${path.basename(filePath)}`);
|
|
156
|
+
await readNewLines(filePath);
|
|
157
|
+
});
|
|
158
|
+
watcher.on('change', async (filePath) => {
|
|
159
|
+
await readNewLines(filePath);
|
|
160
|
+
});
|
|
161
|
+
watcher.on('error', (err) => {
|
|
162
|
+
log(`Watcher error: ${err.message}`);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function startGatewayWatcher() {
|
|
166
|
+
const errLog = path.join(config.openclawDir, 'logs', 'gateway.err.log');
|
|
167
|
+
if (!fs.existsSync(errLog)) {
|
|
168
|
+
log(`Gateway error log not found: ${errLog}`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
let errOffset = 0;
|
|
172
|
+
try {
|
|
173
|
+
errOffset = fs.statSync(errLog).size;
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// start from beginning
|
|
177
|
+
}
|
|
178
|
+
gatewayWatcher = chokidar.watch(errLog, {
|
|
179
|
+
persistent: true,
|
|
180
|
+
ignoreInitial: true,
|
|
181
|
+
});
|
|
182
|
+
gatewayWatcher.on('change', async () => {
|
|
183
|
+
try {
|
|
184
|
+
const stat = fs.statSync(errLog);
|
|
185
|
+
if (stat.size <= errOffset)
|
|
186
|
+
return;
|
|
187
|
+
const fd = fs.openSync(errLog, 'r');
|
|
188
|
+
const buffer = Buffer.alloc(stat.size - errOffset);
|
|
189
|
+
fs.readSync(fd, buffer, 0, buffer.length, errOffset);
|
|
190
|
+
fs.closeSync(fd);
|
|
191
|
+
const lines = buffer.toString('utf-8').split('\n').filter((l) => l.trim());
|
|
192
|
+
for (const line of lines) {
|
|
193
|
+
const event = (0, parser_1.parseGatewayError)(line, 'gateway');
|
|
194
|
+
if (event) {
|
|
195
|
+
await sendEvent(event);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
errOffset = stat.size;
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
202
|
+
log(`Gateway watcher error: ${msg}`);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
log('Gateway error log watcher started');
|
|
206
|
+
}
|
|
207
|
+
function startHeartbeat() {
|
|
208
|
+
const os = require('os');
|
|
209
|
+
heartbeatInterval = setInterval(async () => {
|
|
210
|
+
for (const agentId of activeAgents) {
|
|
211
|
+
await sendEvent({
|
|
212
|
+
agentId,
|
|
213
|
+
agentName: agentId,
|
|
214
|
+
host: os.hostname(),
|
|
215
|
+
type: 'heartbeat',
|
|
216
|
+
timestamp: new Date().toISOString(),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
log(`Heartbeat sent for ${activeAgents.size} agents`);
|
|
220
|
+
}, config.scanIntervalMs);
|
|
221
|
+
}
|
|
222
|
+
async function startCollector(cfg) {
|
|
223
|
+
config = cfg;
|
|
224
|
+
log('=== ClaWatch Collector Starting ===');
|
|
225
|
+
log(`Backend: ${config.backendUrl}`);
|
|
226
|
+
log(`OpenClaw dir: ${config.openclawDir}`);
|
|
227
|
+
loadOffsets();
|
|
228
|
+
await initialScan();
|
|
229
|
+
startFileWatcher();
|
|
230
|
+
startGatewayWatcher();
|
|
231
|
+
startHeartbeat();
|
|
232
|
+
log('Collector running. Watching for changes...');
|
|
233
|
+
}
|
|
234
|
+
function stopCollector() {
|
|
235
|
+
if (watcher) {
|
|
236
|
+
watcher.close();
|
|
237
|
+
watcher = null;
|
|
238
|
+
}
|
|
239
|
+
if (gatewayWatcher) {
|
|
240
|
+
gatewayWatcher.close();
|
|
241
|
+
gatewayWatcher = null;
|
|
242
|
+
}
|
|
243
|
+
if (heartbeatInterval) {
|
|
244
|
+
clearInterval(heartbeatInterval);
|
|
245
|
+
heartbeatInterval = null;
|
|
246
|
+
}
|
|
247
|
+
log('Collector stopped');
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector.js","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ClaWatchConfig {
|
|
2
|
+
openclawDir: string;
|
|
3
|
+
backendUrl: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
scanIntervalMs: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const paths: {
|
|
8
|
+
dir: string;
|
|
9
|
+
config: string;
|
|
10
|
+
pid: string;
|
|
11
|
+
log: string;
|
|
12
|
+
offsets: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function ensureDir(): void;
|
|
15
|
+
export declare function loadConfig(): ClaWatchConfig;
|
|
16
|
+
export declare function saveConfig(config: ClaWatchConfig): void;
|
|
17
|
+
export declare function configExists(): boolean;
|
|
18
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAQD,eAAO,MAAM,KAAK;;;;;;CAMjB,CAAC;AASF,wBAAgB,SAAS,IAAI,IAAI,CAIhC;AAED,wBAAgB,UAAU,IAAI,cAAc,CAM3C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAGvD;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.paths = void 0;
|
|
37
|
+
exports.ensureDir = ensureDir;
|
|
38
|
+
exports.loadConfig = loadConfig;
|
|
39
|
+
exports.saveConfig = saveConfig;
|
|
40
|
+
exports.configExists = configExists;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
const CLAWATCH_DIR = path.join(os.homedir(), '.clawatch');
|
|
45
|
+
const CONFIG_PATH = path.join(CLAWATCH_DIR, 'config.json');
|
|
46
|
+
const PID_PATH = path.join(CLAWATCH_DIR, 'clawatch.pid');
|
|
47
|
+
const LOG_PATH = path.join(CLAWATCH_DIR, 'daemon.log');
|
|
48
|
+
const OFFSETS_PATH = path.join(CLAWATCH_DIR, 'offsets.json');
|
|
49
|
+
exports.paths = {
|
|
50
|
+
dir: CLAWATCH_DIR,
|
|
51
|
+
config: CONFIG_PATH,
|
|
52
|
+
pid: PID_PATH,
|
|
53
|
+
log: LOG_PATH,
|
|
54
|
+
offsets: OFFSETS_PATH,
|
|
55
|
+
};
|
|
56
|
+
const DEFAULT_CONFIG = {
|
|
57
|
+
openclawDir: path.join(os.homedir(), '.openclaw'),
|
|
58
|
+
backendUrl: 'http://localhost:3001',
|
|
59
|
+
apiKey: '',
|
|
60
|
+
scanIntervalMs: 60000,
|
|
61
|
+
};
|
|
62
|
+
function ensureDir() {
|
|
63
|
+
if (!fs.existsSync(CLAWATCH_DIR)) {
|
|
64
|
+
fs.mkdirSync(CLAWATCH_DIR, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function loadConfig() {
|
|
68
|
+
if (!fs.existsSync(CONFIG_PATH)) {
|
|
69
|
+
return DEFAULT_CONFIG;
|
|
70
|
+
}
|
|
71
|
+
const raw = fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
72
|
+
return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
|
|
73
|
+
}
|
|
74
|
+
function saveConfig(config) {
|
|
75
|
+
ensureDir();
|
|
76
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n');
|
|
77
|
+
}
|
|
78
|
+
function configExists() {
|
|
79
|
+
return fs.existsSync(CONFIG_PATH);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,8BAIC;AAED,gCAMC;AAED,gCAGC;AAED,oCAEC;AArDD,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AASzB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;AAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AACvD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AAEhD,QAAA,KAAK,GAAG;IACnB,GAAG,EAAE,YAAY;IACjB,MAAM,EAAE,WAAW;IACnB,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF,MAAM,cAAc,GAAmB;IACrC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC;IACjD,UAAU,EAAE,uBAAuB;IACnC,MAAM,EAAE,EAAE;IACV,cAAc,EAAE,KAAK;CACtB,CAAC;AAEF,SAAgB,SAAS;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,SAAgB,UAAU;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAClD,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,SAAgB,UAAU,CAAC,MAAsB;IAC/C,SAAS,EAAE,CAAC;IACZ,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,SAAgB,YAAY;IAC1B,OAAO,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACpC,CAAC"}
|
package/dist/daemon.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":""}
|
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_1 = require("./config");
|
|
4
|
+
const collector_1 = require("./collector");
|
|
5
|
+
(0, config_1.ensureDir)();
|
|
6
|
+
process.on('SIGTERM', () => {
|
|
7
|
+
(0, collector_1.stopCollector)();
|
|
8
|
+
process.exit(0);
|
|
9
|
+
});
|
|
10
|
+
process.on('SIGINT', () => {
|
|
11
|
+
(0, collector_1.stopCollector)();
|
|
12
|
+
process.exit(0);
|
|
13
|
+
});
|
|
14
|
+
process.on('uncaughtException', (err) => {
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
fs.appendFileSync(config_1.paths.log, `[${new Date().toISOString()}] UNCAUGHT: ${err.message}\n${err.stack}\n`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
const config = (0, config_1.loadConfig)();
|
|
20
|
+
(0, collector_1.startCollector)(config).catch((err) => {
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
fs.appendFileSync(config_1.paths.log, `[${new Date().toISOString()}] FATAL: ${err.message}\n`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":";;AAAA,qCAAwD;AACxD,2CAA4D;AAE5D,IAAA,kBAAS,GAAE,CAAC;AAEZ,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,IAAA,yBAAa,GAAE,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,IAAA,yBAAa,GAAE,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,EAAE,CAAC,cAAc,CAAC,cAAK,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;IACvG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;AAC5B,IAAA,0BAAc,EAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,EAAE,CAAC,cAAc,CAAC,cAAK,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,YAAY,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AgentEvent } from './api';
|
|
2
|
+
interface SessionEvent {
|
|
3
|
+
type: 'session';
|
|
4
|
+
id: string;
|
|
5
|
+
timestamp: string;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
}
|
|
8
|
+
interface MessageEvent {
|
|
9
|
+
type: 'message';
|
|
10
|
+
timestamp: string;
|
|
11
|
+
message?: {
|
|
12
|
+
role?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
usage?: {
|
|
15
|
+
input?: number;
|
|
16
|
+
output?: number;
|
|
17
|
+
cacheRead?: number;
|
|
18
|
+
cacheWrite?: number;
|
|
19
|
+
totalTokens?: number;
|
|
20
|
+
cost?: {
|
|
21
|
+
input?: number;
|
|
22
|
+
output?: number;
|
|
23
|
+
cacheRead?: number;
|
|
24
|
+
cacheWrite?: number;
|
|
25
|
+
total?: number;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
type JsonlEvent = SessionEvent | MessageEvent | {
|
|
31
|
+
type: string;
|
|
32
|
+
timestamp?: string;
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
};
|
|
35
|
+
export declare function parseLine(line: string): JsonlEvent | null;
|
|
36
|
+
export declare function mapEventToApiEvents(event: JsonlEvent, agentId: string): AgentEvent[];
|
|
37
|
+
export declare function parseGatewayError(line: string, agentId: string): AgentEvent | null;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAInC,UAAU,YAAY;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE;YACN,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,IAAI,CAAC,EAAE;gBACL,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,MAAM,CAAC,EAAE,MAAM,CAAC;gBAChB,SAAS,CAAC,EAAE,MAAM,CAAC;gBACnB,UAAU,CAAC,EAAE,MAAM,CAAC;gBACpB,KAAK,CAAC,EAAE,MAAM,CAAC;aAChB,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,KAAK,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAE7G,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQzD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CA6CpF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAYlF"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseLine = parseLine;
|
|
37
|
+
exports.mapEventToApiEvents = mapEventToApiEvents;
|
|
38
|
+
exports.parseGatewayError = parseGatewayError;
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
const HOST = os.hostname();
|
|
41
|
+
function parseLine(line) {
|
|
42
|
+
const trimmed = line.trim();
|
|
43
|
+
if (!trimmed)
|
|
44
|
+
return null;
|
|
45
|
+
try {
|
|
46
|
+
return JSON.parse(trimmed);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function mapEventToApiEvents(event, agentId) {
|
|
53
|
+
const agentName = agentId;
|
|
54
|
+
const timestamp = event.timestamp || new Date().toISOString();
|
|
55
|
+
const results = [];
|
|
56
|
+
if (event.type === 'session') {
|
|
57
|
+
results.push({
|
|
58
|
+
agentId,
|
|
59
|
+
agentName,
|
|
60
|
+
host: HOST,
|
|
61
|
+
type: 'status_change',
|
|
62
|
+
data: { status: 'running' },
|
|
63
|
+
timestamp,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (event.type === 'message') {
|
|
67
|
+
const msg = event.message;
|
|
68
|
+
if (msg?.usage?.cost?.total !== undefined) {
|
|
69
|
+
results.push({
|
|
70
|
+
agentId,
|
|
71
|
+
agentName,
|
|
72
|
+
host: HOST,
|
|
73
|
+
type: 'cost',
|
|
74
|
+
data: {
|
|
75
|
+
costUsd: msg.usage.cost.total,
|
|
76
|
+
tokenCount: msg.usage.totalTokens || 0,
|
|
77
|
+
model: msg.model || 'unknown',
|
|
78
|
+
},
|
|
79
|
+
timestamp,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (msg?.role === 'assistant') {
|
|
83
|
+
results.push({
|
|
84
|
+
agentId,
|
|
85
|
+
agentName,
|
|
86
|
+
host: HOST,
|
|
87
|
+
type: 'heartbeat',
|
|
88
|
+
timestamp,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
function parseGatewayError(line, agentId) {
|
|
95
|
+
const trimmed = line.trim();
|
|
96
|
+
if (!trimmed)
|
|
97
|
+
return null;
|
|
98
|
+
return {
|
|
99
|
+
agentId,
|
|
100
|
+
agentName: agentId,
|
|
101
|
+
host: HOST,
|
|
102
|
+
type: 'error',
|
|
103
|
+
data: { error: trimmed },
|
|
104
|
+
timestamp: new Date().toISOString(),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,8BAQC;AAED,kDA6CC;AAED,8CAYC;AA1GD,uCAAyB;AAGzB,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;AAkC3B,SAAgB,SAAS,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,KAAiB,EAAE,OAAe;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC;IAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9D,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC;YACX,OAAO;YACP,SAAS;YACT,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;YAC3B,SAAS;SACV,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAI,KAAsB,CAAC,OAAO,CAAC;QAC5C,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC;gBACX,OAAO;gBACP,SAAS;gBACT,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;oBAC7B,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC;oBACtC,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,SAAS;iBAC9B;gBACD,SAAS;aACV,CAAC,CAAC;QACL,CAAC;QAED,IAAI,GAAG,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC;gBACX,OAAO;gBACP,SAAS;gBACT,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,WAAW;gBACjB,SAAS;aACV,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,iBAAiB,CAAC,IAAY,EAAE,OAAe;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,OAAO;QACL,OAAO;QACP,SAAS,EAAE,OAAO;QAClB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clawatch",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Observability & monitoring for AI agents. Track costs, tokens, sessions, and get alerts when things go wrong.",
|
|
5
|
+
"author": "GENWAY AI <hello@genway.ai>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://clawatch.dev",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/GENWAY-AI/clawatch.git",
|
|
11
|
+
"directory": "cli"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/GENWAY-AI/clawatch/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ai",
|
|
18
|
+
"agents",
|
|
19
|
+
"observability",
|
|
20
|
+
"monitoring",
|
|
21
|
+
"openclaw",
|
|
22
|
+
"llm",
|
|
23
|
+
"cost-tracking",
|
|
24
|
+
"opentelemetry"
|
|
25
|
+
],
|
|
26
|
+
"main": "dist/cli.js",
|
|
27
|
+
"bin": {
|
|
28
|
+
"clawatch": "./dist/cli.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist/**/*",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc",
|
|
40
|
+
"dev": "tsc --watch",
|
|
41
|
+
"start": "node dist/cli.js",
|
|
42
|
+
"prepublishOnly": "npm run build"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"chalk": "^4.1.2",
|
|
46
|
+
"chokidar": "^3.6.0",
|
|
47
|
+
"commander": "^12.1.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^20.14.0",
|
|
51
|
+
"typescript": "^5.5.0"
|
|
52
|
+
}
|
|
53
|
+
}
|