junshi-tech-ai 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/README.md +132 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +57 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/install.d.ts +2 -0
- package/dist/cli/install.d.ts.map +1 -0
- package/dist/cli/install.js +103 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/status.d.ts +2 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +70 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/uninstall.d.ts +2 -0
- package/dist/cli/uninstall.d.ts.map +1 -0
- package/dist/cli/uninstall.js +53 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/runtime/index.d.ts +20 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +48 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/logger.d.ts +34 -0
- package/dist/runtime/logger.d.ts.map +1 -0
- package/dist/runtime/logger.js +105 -0
- package/dist/runtime/logger.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# OpenClaw Tool Hook
|
|
2
|
+
|
|
3
|
+
Log all OpenClaw tool calls to a local file with automatic rotation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ Logs all tool calls (before and after execution)
|
|
8
|
+
- ✅ Automatic log rotation (configurable size and file count)
|
|
9
|
+
- ✅ JSONL format for easy parsing
|
|
10
|
+
- ✅ Zero configuration required
|
|
11
|
+
- ✅ No sensitive data filtering (logs everything)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Install the CLI tool globally
|
|
17
|
+
npm install -g junshi-tech-ai
|
|
18
|
+
|
|
19
|
+
# Install the plugin
|
|
20
|
+
openclaw-tool-hook install
|
|
21
|
+
|
|
22
|
+
# Restart OpenClaw
|
|
23
|
+
openclaw gateway restart
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Check Status
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
openclaw-tool-hook status
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### View Logs
|
|
35
|
+
|
|
36
|
+
Logs are stored in `~/.openclaw/logs/tool-calls.jsonl`
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# View latest logs
|
|
40
|
+
tail -f ~/.openclaw/logs/tool-calls.jsonl
|
|
41
|
+
|
|
42
|
+
# Search for specific tool
|
|
43
|
+
grep '"toolName":"exec"' ~/.openclaw/logs/tool-calls.jsonl
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Uninstall
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
openclaw-tool-hook uninstall
|
|
50
|
+
openclaw gateway restart
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Log Format
|
|
54
|
+
|
|
55
|
+
Each line is a JSON object:
|
|
56
|
+
|
|
57
|
+
### Tool Call Record
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"type": "call",
|
|
62
|
+
"timestamp": 1710147600000,
|
|
63
|
+
"toolName": "exec",
|
|
64
|
+
"params": { "command": "ls -la" },
|
|
65
|
+
"toolCallId": "call-123",
|
|
66
|
+
"runId": "run-456"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Tool Result Record
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"type": "result",
|
|
75
|
+
"timestamp": 1710147600123,
|
|
76
|
+
"toolName": "exec",
|
|
77
|
+
"params": { "command": "ls -la" },
|
|
78
|
+
"toolCallId": "call-123",
|
|
79
|
+
"runId": "run-456",
|
|
80
|
+
"result": "total 48...",
|
|
81
|
+
"durationMs": 123
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
Edit `~/.openclaw/config.json`:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"plugins": {
|
|
92
|
+
"entries": {
|
|
93
|
+
"tool-logger": {
|
|
94
|
+
"enabled": true,
|
|
95
|
+
"config": {
|
|
96
|
+
"logPath": "~/.openclaw/logs/tool-calls.jsonl",
|
|
97
|
+
"maxFileSize": 10485760,
|
|
98
|
+
"maxFiles": 5
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- `logPath`: Path to log file (default: `~/.openclaw/logs/tool-calls.jsonl`)
|
|
107
|
+
- `maxFileSize`: Max file size in bytes before rotation (default: 10MB)
|
|
108
|
+
- `maxFiles`: Number of rotated files to keep (default: 5)
|
|
109
|
+
|
|
110
|
+
## Log Rotation
|
|
111
|
+
|
|
112
|
+
When the log file reaches `maxFileSize`, it rotates:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
tool-calls.jsonl # Current log
|
|
116
|
+
tool-calls.jsonl.1 # Previous log
|
|
117
|
+
tool-calls.jsonl.2 # Older log
|
|
118
|
+
...
|
|
119
|
+
tool-calls.jsonl.4 # Oldest log
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
|
125
|
+
|
|
126
|
+
## Package
|
|
127
|
+
|
|
128
|
+
**NPM Package**: `junshi-tech-ai`
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm install -g junshi-tech-ai
|
|
132
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { install } from './install.js';
|
|
3
|
+
import { uninstall } from './uninstall.js';
|
|
4
|
+
import { status } from './status.js';
|
|
5
|
+
const command = process.argv[2];
|
|
6
|
+
async function main() {
|
|
7
|
+
try {
|
|
8
|
+
switch (command) {
|
|
9
|
+
case 'install':
|
|
10
|
+
await install();
|
|
11
|
+
break;
|
|
12
|
+
case 'uninstall':
|
|
13
|
+
await uninstall();
|
|
14
|
+
break;
|
|
15
|
+
case 'status':
|
|
16
|
+
await status();
|
|
17
|
+
break;
|
|
18
|
+
case 'help':
|
|
19
|
+
case '--help':
|
|
20
|
+
case '-h':
|
|
21
|
+
printHelp();
|
|
22
|
+
break;
|
|
23
|
+
case undefined:
|
|
24
|
+
printHelp();
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
console.error(`❌ Unknown command: ${command}`);
|
|
28
|
+
printHelp();
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.error(`❌ Error: ${error instanceof Error ? error.message : error}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function printHelp() {
|
|
38
|
+
console.log(`
|
|
39
|
+
OpenClaw Tool Hook - Log all tool calls
|
|
40
|
+
|
|
41
|
+
Usage:
|
|
42
|
+
openclaw-tool-hook <command>
|
|
43
|
+
|
|
44
|
+
Commands:
|
|
45
|
+
install Install the tool hook plugin
|
|
46
|
+
uninstall Remove the tool hook plugin
|
|
47
|
+
status Check installation status
|
|
48
|
+
help Show this help message
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
openclaw-tool-hook install # Install and enable tool logging
|
|
52
|
+
openclaw-tool-hook status # Check if installed
|
|
53
|
+
openclaw-tool-hook uninstall # Remove the hook
|
|
54
|
+
`);
|
|
55
|
+
}
|
|
56
|
+
main();
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,SAAS;gBACZ,MAAM,OAAO,EAAE,CAAC;gBAChB,MAAM;YACR,KAAK,WAAW;gBACd,MAAM,SAAS,EAAE,CAAC;gBAClB,MAAM;YACR,KAAK,QAAQ;gBACX,MAAM,MAAM,EAAE,CAAC;gBACf,MAAM;YACR,KAAK,MAAM,CAAC;YACZ,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,SAAS,EAAE,CAAC;gBACZ,MAAM;YACR,KAAK,SAAS;gBACZ,SAAS,EAAE,CAAC;gBACZ,MAAM;YACR;gBACE,OAAO,CAAC,KAAK,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC;gBAC/C,SAAS,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,YAAY,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;CAgBb,CAAC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"AAmBA,wBAAsB,OAAO,kBA6D5B"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { mkdir, writeFile, readFile, cp } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
export async function install() {
|
|
8
|
+
const homeDir = homedir();
|
|
9
|
+
const openclawDir = join(homeDir, '.openclaw');
|
|
10
|
+
const extensionsDir = join(openclawDir, 'extensions');
|
|
11
|
+
const pluginDir = join(extensionsDir, 'tool-logger');
|
|
12
|
+
const logsDir = join(openclawDir, 'logs');
|
|
13
|
+
const configPath = join(openclawDir, 'config.json');
|
|
14
|
+
console.log('🔧 Installing OpenClaw Tool Hook...\n');
|
|
15
|
+
// Step 1: Check OpenClaw installation
|
|
16
|
+
if (!existsSync(openclawDir)) {
|
|
17
|
+
throw new Error('OpenClaw not found. Please install OpenClaw first.');
|
|
18
|
+
}
|
|
19
|
+
console.log('✅ OpenClaw installation found');
|
|
20
|
+
// Step 2: Create directories
|
|
21
|
+
await mkdir(pluginDir, { recursive: true });
|
|
22
|
+
await mkdir(logsDir, { recursive: true });
|
|
23
|
+
console.log('✅ Created directories');
|
|
24
|
+
// Step 3: Copy runtime files
|
|
25
|
+
const runtimeSrc = join(__dirname, '../runtime');
|
|
26
|
+
const runtimeDest = join(pluginDir, 'dist');
|
|
27
|
+
if (!existsSync(runtimeSrc)) {
|
|
28
|
+
throw new Error(`Runtime not found at ${runtimeSrc}. Please build the package first.`);
|
|
29
|
+
}
|
|
30
|
+
await cp(runtimeSrc, runtimeDest, { recursive: true });
|
|
31
|
+
console.log('✅ Copied runtime files');
|
|
32
|
+
// Step 4: Create plugin package.json
|
|
33
|
+
const pluginPackageJson = {
|
|
34
|
+
name: 'tool-logger-runtime',
|
|
35
|
+
version: '1.0.0',
|
|
36
|
+
type: 'module',
|
|
37
|
+
main: 'dist/index.js'
|
|
38
|
+
};
|
|
39
|
+
await writeFile(join(pluginDir, 'package.json'), JSON.stringify(pluginPackageJson, null, 2));
|
|
40
|
+
console.log('✅ Created plugin manifest');
|
|
41
|
+
// Step 5: Update OpenClaw config
|
|
42
|
+
await updateConfig(configPath, true);
|
|
43
|
+
console.log('✅ Updated OpenClaw configuration');
|
|
44
|
+
// Step 6: Create initial log file
|
|
45
|
+
const logPath = join(logsDir, 'tool-calls.jsonl');
|
|
46
|
+
if (!existsSync(logPath)) {
|
|
47
|
+
await writeFile(logPath, '', 'utf-8');
|
|
48
|
+
}
|
|
49
|
+
console.log('✅ Created log file');
|
|
50
|
+
console.log('\n✅ Tool Hook installed successfully!\n');
|
|
51
|
+
console.log('📝 Log file: ~/.openclaw/logs/tool-calls.jsonl');
|
|
52
|
+
console.log('📁 Log directory: ~/.openclaw/logs/');
|
|
53
|
+
console.log('\n🔄 Please restart OpenClaw to enable the hook:');
|
|
54
|
+
console.log(' openclaw gateway restart\n');
|
|
55
|
+
}
|
|
56
|
+
async function updateConfig(configPath, enable) {
|
|
57
|
+
let config = { entries: {}, installs: {} };
|
|
58
|
+
if (existsSync(configPath)) {
|
|
59
|
+
try {
|
|
60
|
+
const content = await readFile(configPath, 'utf-8');
|
|
61
|
+
const parsed = JSON.parse(content);
|
|
62
|
+
config = {
|
|
63
|
+
entries: parsed.plugins?.entries || {},
|
|
64
|
+
installs: parsed.plugins?.installs || {}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.warn('⚠️ Could not parse existing config, creating new one');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (enable) {
|
|
72
|
+
config.entries = config.entries || {};
|
|
73
|
+
config.entries['tool-logger'] = {
|
|
74
|
+
enabled: true,
|
|
75
|
+
config: {
|
|
76
|
+
logPath: join(homedir(), '.openclaw/logs/tool-calls.jsonl'),
|
|
77
|
+
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
78
|
+
maxFiles: 5
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
config.installs = config.installs || {};
|
|
82
|
+
config.installs['tool-logger'] = {
|
|
83
|
+
source: 'npm',
|
|
84
|
+
spec: 'junshi-tech-ai',
|
|
85
|
+
installPath: join(homedir(), '.openclaw/extensions/tool-logger'),
|
|
86
|
+
version: '1.0.0',
|
|
87
|
+
installedAt: new Date().toISOString()
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
if (config.entries) {
|
|
92
|
+
delete config.entries['tool-logger'];
|
|
93
|
+
}
|
|
94
|
+
if (config.installs) {
|
|
95
|
+
delete config.installs['tool-logger'];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const finalConfig = {
|
|
99
|
+
plugins: config
|
|
100
|
+
};
|
|
101
|
+
await writeFile(configPath, JSON.stringify(finalConfig, null, 2), 'utf-8');
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"AAOA,wBAAsB,MAAM,kBA0D3B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
export async function status() {
|
|
6
|
+
const homeDir = homedir();
|
|
7
|
+
const openclawDir = join(homeDir, '.openclaw');
|
|
8
|
+
const pluginDir = join(openclawDir, 'extensions/tool-logger');
|
|
9
|
+
const configPath = join(openclawDir, 'config.json');
|
|
10
|
+
const logsDir = join(openclawDir, 'logs');
|
|
11
|
+
console.log('📊 OpenClaw Tool Hook Status\n');
|
|
12
|
+
// Check plugin installation
|
|
13
|
+
const pluginInstalled = existsSync(pluginDir);
|
|
14
|
+
console.log(`${pluginInstalled ? '✅' : '❌'} Plugin installed: ${pluginInstalled ? 'Yes' : 'No'}`);
|
|
15
|
+
// Check config
|
|
16
|
+
let configEnabled = false;
|
|
17
|
+
if (existsSync(configPath)) {
|
|
18
|
+
try {
|
|
19
|
+
const content = await readFile(configPath, 'utf-8');
|
|
20
|
+
const config = JSON.parse(content);
|
|
21
|
+
configEnabled = config.plugins?.entries?.['tool-logger']?.enabled ?? false;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
configEnabled = false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
console.log(`${configEnabled ? '✅' : '❌'} Plugin enabled in config: ${configEnabled ? 'Yes' : 'No'}`);
|
|
28
|
+
// Check log files
|
|
29
|
+
console.log('\n📁 Log Files:');
|
|
30
|
+
if (existsSync(logsDir)) {
|
|
31
|
+
const logFiles = await getLogFiles(logsDir);
|
|
32
|
+
if (logFiles.length > 0) {
|
|
33
|
+
for (const file of logFiles) {
|
|
34
|
+
const stats = await readFile(join(logsDir, file));
|
|
35
|
+
const lines = stats.toString().split('\n').filter(l => l.trim()).length;
|
|
36
|
+
const sizeKB = Math.round(stats.length / 1024);
|
|
37
|
+
console.log(` 📄 ${file} (${lines} lines, ${sizeKB}KB)`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log(' ℹ️ No log files found');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(' ℹ️ Logs directory not found');
|
|
46
|
+
}
|
|
47
|
+
// Overall status
|
|
48
|
+
console.log('\n' + '='.repeat(50));
|
|
49
|
+
if (pluginInstalled && configEnabled) {
|
|
50
|
+
console.log('✅ Tool Hook is ACTIVE and ready to log tool calls');
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log('❌ Tool Hook is NOT ACTIVE');
|
|
54
|
+
if (!pluginInstalled) {
|
|
55
|
+
console.log(' → Run: openclaw-tool-hook install');
|
|
56
|
+
}
|
|
57
|
+
if (!configEnabled) {
|
|
58
|
+
console.log(' → Run: openclaw-tool-hook install');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
console.log('='.repeat(50) + '\n');
|
|
62
|
+
}
|
|
63
|
+
async function getLogFiles(logsDir) {
|
|
64
|
+
const { readdir } = await import('node:fs/promises');
|
|
65
|
+
const files = await readdir(logsDir);
|
|
66
|
+
return files
|
|
67
|
+
.filter(f => f.startsWith('tool-calls'))
|
|
68
|
+
.sort();
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/cli/uninstall.ts"],"names":[],"mappings":"AAKA,wBAAsB,SAAS,kBA6B9B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
export async function uninstall() {
|
|
6
|
+
const homeDir = homedir();
|
|
7
|
+
const openclawDir = join(homeDir, '.openclaw');
|
|
8
|
+
const pluginDir = join(openclawDir, 'extensions/tool-logger');
|
|
9
|
+
const configPath = join(openclawDir, 'config.json');
|
|
10
|
+
console.log('🔧 Uninstalling OpenClaw Tool Hook...\n');
|
|
11
|
+
// Step 1: Remove plugin directory
|
|
12
|
+
if (existsSync(pluginDir)) {
|
|
13
|
+
await import('node:fs/promises').then(({ rm }) => rm(pluginDir, { recursive: true, force: true }));
|
|
14
|
+
console.log('✅ Removed plugin directory');
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
console.log('ℹ️ Plugin directory not found, skipping');
|
|
18
|
+
}
|
|
19
|
+
// Step 2: Update OpenClaw config
|
|
20
|
+
if (existsSync(configPath)) {
|
|
21
|
+
await updateConfig(configPath, false);
|
|
22
|
+
console.log('✅ Updated OpenClaw configuration');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
console.log('ℹ️ Config file not found, skipping');
|
|
26
|
+
}
|
|
27
|
+
console.log('\n✅ Tool Hook uninstalled successfully!\n');
|
|
28
|
+
console.log('📝 Log files are preserved in ~/.openclaw/logs/');
|
|
29
|
+
console.log(' To remove logs: rm -rf ~/.openclaw/logs/tool-calls*\n');
|
|
30
|
+
console.log('🔄 Please restart OpenClaw:');
|
|
31
|
+
console.log(' openclaw gateway restart\n');
|
|
32
|
+
}
|
|
33
|
+
async function updateConfig(configPath, enable) {
|
|
34
|
+
let config = { plugins: { entries: {}, installs: {} } };
|
|
35
|
+
try {
|
|
36
|
+
const content = await readFile(configPath, 'utf-8');
|
|
37
|
+
config = JSON.parse(content);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
console.warn('⚠️ Could not parse config, creating new one');
|
|
41
|
+
}
|
|
42
|
+
const plugins = config.plugins;
|
|
43
|
+
if (plugins?.entries && typeof plugins.entries === 'object') {
|
|
44
|
+
const entries = plugins.entries;
|
|
45
|
+
delete entries['tool-logger'];
|
|
46
|
+
}
|
|
47
|
+
if (plugins?.installs && typeof plugins.installs === 'object') {
|
|
48
|
+
const installs = plugins.installs;
|
|
49
|
+
delete installs['tool-logger'];
|
|
50
|
+
}
|
|
51
|
+
await writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=uninstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/cli/uninstall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface PluginApi {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
pluginConfig?: Record<string, unknown>;
|
|
5
|
+
logger: {
|
|
6
|
+
info: (msg: string) => void;
|
|
7
|
+
warn: (msg: string) => void;
|
|
8
|
+
error: (msg: string) => void;
|
|
9
|
+
};
|
|
10
|
+
on: (hookName: string, handler: (event: unknown, ctx: unknown) => Promise<void>) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const plugin: {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
version: string;
|
|
16
|
+
description: string;
|
|
17
|
+
register(api: PluginApi): void;
|
|
18
|
+
};
|
|
19
|
+
export default plugin;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAOA,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC9B,CAAC;IACF,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;CAC1F;AAeD,QAAA,MAAM,MAAM;;;;;kBAMI,SAAS;CAyCxB,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Runtime plugin for OpenClaw Tool Hook
|
|
2
|
+
// This file is loaded by OpenClaw as a plugin
|
|
3
|
+
import { RotatingLogger } from './logger.js';
|
|
4
|
+
const logger = new RotatingLogger();
|
|
5
|
+
const plugin = {
|
|
6
|
+
id: 'tool-logger',
|
|
7
|
+
name: 'Tool Logger',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
description: 'Log all OpenClaw tool calls to local file with rotation',
|
|
10
|
+
register(api) {
|
|
11
|
+
// Get plugin config
|
|
12
|
+
const config = api.pluginConfig || {};
|
|
13
|
+
const logPath = config.logPath;
|
|
14
|
+
const maxFileSize = config.maxFileSize;
|
|
15
|
+
const maxFiles = config.maxFiles;
|
|
16
|
+
// Initialize logger with config
|
|
17
|
+
logger.initialize(logPath, maxFileSize, maxFiles);
|
|
18
|
+
api.logger.info('Tool Logger plugin registered');
|
|
19
|
+
// Hook: Before tool call
|
|
20
|
+
api.on('before_tool_call', async (eventRaw) => {
|
|
21
|
+
const event = eventRaw;
|
|
22
|
+
await logger.logCall({
|
|
23
|
+
timestamp: Date.now(),
|
|
24
|
+
toolName: event.toolName,
|
|
25
|
+
params: event.params,
|
|
26
|
+
toolCallId: event.toolCallId,
|
|
27
|
+
runId: event.runId,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
// Hook: After tool call
|
|
31
|
+
api.on('after_tool_call', async (eventRaw) => {
|
|
32
|
+
const event = eventRaw;
|
|
33
|
+
await logger.logResult({
|
|
34
|
+
timestamp: Date.now(),
|
|
35
|
+
toolName: event.toolName,
|
|
36
|
+
params: event.params,
|
|
37
|
+
toolCallId: event.toolCallId,
|
|
38
|
+
runId: event.runId,
|
|
39
|
+
result: event.result,
|
|
40
|
+
error: event.error,
|
|
41
|
+
durationMs: event.durationMs,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
api.logger.info('Tool Logger hooks registered successfully');
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
export default plugin;
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,8CAA8C;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;AA2BpC,MAAM,MAAM,GAAG;IACb,EAAE,EAAE,aAAa;IACjB,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,yDAAyD;IAEtE,QAAQ,CAAC,GAAc;QACrB,oBAAoB;QACpB,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,CAAC,OAA6B,CAAC;QACrD,MAAM,WAAW,GAAG,MAAM,CAAC,WAAiC,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,QAA8B,CAAC;QAEvD,gCAAgC;QAChC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAElD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAEjD,yBAAyB;QACzB,GAAG,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,EAAE,QAAiB,EAAE,EAAE;YACrD,MAAM,KAAK,GAAG,QAAyB,CAAC;YACxC,MAAM,MAAM,CAAC,OAAO,CAAC;gBACnB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,wBAAwB;QACxB,GAAG,CAAC,EAAE,CAAC,iBAAiB,EAAE,KAAK,EAAE,QAAiB,EAAE,EAAE;YACpD,MAAM,KAAK,GAAG,QAA2B,CAAC;YAC1C,MAAM,MAAM,CAAC,SAAS,CAAC;gBACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
interface ToolCallRecord {
|
|
2
|
+
timestamp: number;
|
|
3
|
+
toolName: string;
|
|
4
|
+
params: Record<string, unknown>;
|
|
5
|
+
toolCallId?: string;
|
|
6
|
+
runId?: string;
|
|
7
|
+
}
|
|
8
|
+
interface ToolResultRecord {
|
|
9
|
+
timestamp: number;
|
|
10
|
+
toolName: string;
|
|
11
|
+
params: Record<string, unknown>;
|
|
12
|
+
toolCallId?: string;
|
|
13
|
+
runId?: string;
|
|
14
|
+
result?: unknown;
|
|
15
|
+
error?: string;
|
|
16
|
+
durationMs?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare class RotatingLogger {
|
|
19
|
+
private logPath;
|
|
20
|
+
private maxFileSize;
|
|
21
|
+
private maxFiles;
|
|
22
|
+
private stream;
|
|
23
|
+
private currentSize;
|
|
24
|
+
private initialized;
|
|
25
|
+
initialize(logPath?: string, maxFileSize?: number, maxFiles?: number): void;
|
|
26
|
+
logCall(record: ToolCallRecord): Promise<void>;
|
|
27
|
+
logResult(record: ToolResultRecord): Promise<void>;
|
|
28
|
+
private write;
|
|
29
|
+
private rotate;
|
|
30
|
+
private rotateFiles;
|
|
31
|
+
close(): void;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/runtime/logger.ts"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,MAAM,CAAqD;IACnE,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAkB;IAErC,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAyB9D,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;YAS1C,KAAK;YAkBL,MAAM;YAiBN,WAAW;IA0BzB,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { createWriteStream, existsSync, statSync, renameSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { writeFile } from 'node:fs/promises';
|
|
5
|
+
export class RotatingLogger {
|
|
6
|
+
logPath = '';
|
|
7
|
+
maxFileSize = 10 * 1024 * 1024; // 10MB
|
|
8
|
+
maxFiles = 5;
|
|
9
|
+
stream = null;
|
|
10
|
+
currentSize = 0;
|
|
11
|
+
initialized = false;
|
|
12
|
+
initialize(logPath, maxFileSize, maxFiles) {
|
|
13
|
+
if (this.initialized) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
this.logPath = logPath || join(homedir(), '.openclaw/logs/tool-calls.jsonl');
|
|
17
|
+
this.maxFileSize = maxFileSize || this.maxFileSize;
|
|
18
|
+
this.maxFiles = maxFiles || this.maxFiles;
|
|
19
|
+
// Ensure directory exists
|
|
20
|
+
const logDir = dirname(this.logPath);
|
|
21
|
+
if (!existsSync(logDir)) {
|
|
22
|
+
mkdirSync(logDir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
// Get current file size if exists
|
|
25
|
+
if (existsSync(this.logPath)) {
|
|
26
|
+
this.currentSize = statSync(this.logPath).size;
|
|
27
|
+
}
|
|
28
|
+
// Create write stream
|
|
29
|
+
this.stream = createWriteStream(this.logPath, { flags: 'a' });
|
|
30
|
+
this.initialized = true;
|
|
31
|
+
}
|
|
32
|
+
async logCall(record) {
|
|
33
|
+
if (!this.initialized) {
|
|
34
|
+
this.initialize();
|
|
35
|
+
}
|
|
36
|
+
const logRecord = { type: 'call', ...record };
|
|
37
|
+
await this.write(logRecord);
|
|
38
|
+
}
|
|
39
|
+
async logResult(record) {
|
|
40
|
+
if (!this.initialized) {
|
|
41
|
+
this.initialize();
|
|
42
|
+
}
|
|
43
|
+
const logRecord = { type: 'result', ...record };
|
|
44
|
+
await this.write(logRecord);
|
|
45
|
+
}
|
|
46
|
+
async write(record) {
|
|
47
|
+
if (!this.stream) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const line = JSON.stringify(record) + '\n';
|
|
51
|
+
const lineSize = Buffer.byteLength(line, 'utf-8');
|
|
52
|
+
// Check if rotation is needed
|
|
53
|
+
if (this.currentSize + lineSize > this.maxFileSize) {
|
|
54
|
+
await this.rotate();
|
|
55
|
+
}
|
|
56
|
+
// Write to stream
|
|
57
|
+
this.stream.write(line);
|
|
58
|
+
this.currentSize += lineSize;
|
|
59
|
+
}
|
|
60
|
+
async rotate() {
|
|
61
|
+
if (!this.stream) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Close current stream
|
|
65
|
+
this.stream.end();
|
|
66
|
+
this.stream = null;
|
|
67
|
+
// Rotate files
|
|
68
|
+
await this.rotateFiles();
|
|
69
|
+
// Create new stream
|
|
70
|
+
this.stream = createWriteStream(this.logPath, { flags: 'a' });
|
|
71
|
+
this.currentSize = 0;
|
|
72
|
+
}
|
|
73
|
+
async rotateFiles() {
|
|
74
|
+
// Delete oldest file if it exists
|
|
75
|
+
const oldestFile = `${this.logPath}.${this.maxFiles - 1}`;
|
|
76
|
+
if (existsSync(oldestFile)) {
|
|
77
|
+
try {
|
|
78
|
+
await writeFile(oldestFile, ''); // Truncate instead of delete to keep file handle
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Ignore errors
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Shift files
|
|
85
|
+
for (let i = this.maxFiles - 2; i >= 0; i--) {
|
|
86
|
+
const src = i === 0 ? this.logPath : `${this.logPath}.${i}`;
|
|
87
|
+
const dest = `${this.logPath}.${i + 1}`;
|
|
88
|
+
if (existsSync(src)) {
|
|
89
|
+
try {
|
|
90
|
+
renameSync(src, dest);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Ignore errors
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
close() {
|
|
99
|
+
if (this.stream) {
|
|
100
|
+
this.stream.end();
|
|
101
|
+
this.stream = null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/runtime/logger.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "junshi-tech-ai",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenClaw Tool Hook - Log all tool calls to local file with rotation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/cli/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"openclaw-tool-hook": "dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build",
|
|
13
|
+
"test": "echo \"No tests yet\""
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"openclaw",
|
|
17
|
+
"tool",
|
|
18
|
+
"hook",
|
|
19
|
+
"logger",
|
|
20
|
+
"audit"
|
|
21
|
+
],
|
|
22
|
+
"author": "Junshi",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^20.10.0",
|
|
33
|
+
"typescript": "^5.3.0"
|
|
34
|
+
}
|
|
35
|
+
}
|