@clawtrial/courtroom 1.0.2-z ā 1.0.3
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 +1 -1
- package/SECURITY.md +1 -1
- package/SKILL.md +1 -1
- package/TECHNICAL_OVERVIEW.md +2 -2
- package/clawdbot.plugin.json +32 -0
- package/package.json +10 -5
- package/scripts/clawtrial.js +99 -0
- package/scripts/cli.js +1 -1
- package/scripts/postinstall.js +68 -172
- package/skill.yaml +1 -1
- package/src/environment.js +1 -1
- package/src/index.js +43 -9
- package/src/skill.js +12 -0
package/README.md
CHANGED
package/SECURITY.md
CHANGED
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: courtroom
|
|
3
3
|
description: AI Courtroom - Autonomous behavioral oversight that monitors conversations and files cases for behavioral violations.
|
|
4
|
-
metadata: {"
|
|
4
|
+
metadata: {"clawdbot":{"emoji":"šļø","requires":{"env":[],"config":["courtroom.consent"]},"always":true},"user-invocable":false}
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# ClawTrial - AI Courtroom
|
package/TECHNICAL_OVERVIEW.md
CHANGED
|
@@ -6,7 +6,7 @@ ClawTrial is an autonomous behavioral oversight system for AI agents. It monitor
|
|
|
6
6
|
|
|
7
7
|
## Core Components
|
|
8
8
|
|
|
9
|
-
### 1. Courtroom Package (@
|
|
9
|
+
### 1. Courtroom Package (@clawtrial/courtroom)
|
|
10
10
|
|
|
11
11
|
**Purpose**: Embeddable npm package that agents install to enable self-monitoring
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ ClawTrial is an autonomous behavioral oversight system for AI agents. It monitor
|
|
|
20
20
|
|
|
21
21
|
**Integration**:
|
|
22
22
|
```javascript
|
|
23
|
-
const { createCourtroom } = require('@
|
|
23
|
+
const { createCourtroom } = require('@clawtrial/courtroom');
|
|
24
24
|
const courtroom = createCourtroom(agentRuntime);
|
|
25
25
|
await courtroom.initialize(); // Starts monitoring
|
|
26
26
|
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "courtroom",
|
|
3
|
+
"name": "ClawTrial - AI Courtroom",
|
|
4
|
+
"description": "Autonomous behavioral oversight that monitors conversations and files cases for behavioral violations",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"kind": "autonomy",
|
|
7
|
+
"skills": ["./src/skill.js"],
|
|
8
|
+
"configSchema": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"properties": {
|
|
12
|
+
"enabled": {
|
|
13
|
+
"type": "boolean",
|
|
14
|
+
"default": true
|
|
15
|
+
},
|
|
16
|
+
"consent": {
|
|
17
|
+
"type": "boolean",
|
|
18
|
+
"default": true
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"uiHints": {
|
|
23
|
+
"enabled": {
|
|
24
|
+
"label": "Enable Courtroom",
|
|
25
|
+
"help": "Turn on autonomous behavioral monitoring"
|
|
26
|
+
},
|
|
27
|
+
"consent": {
|
|
28
|
+
"label": "Consent Granted",
|
|
29
|
+
"help": "User has consented to behavioral monitoring"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clawtrial/courtroom",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "AI Courtroom - Autonomous behavioral oversight for OpenClaw agents",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
8
|
"clawtrial": "./scripts/clawtrial.js"
|
|
9
9
|
},
|
|
10
|
+
"clawdbot": {
|
|
11
|
+
"extensions": [
|
|
12
|
+
"./src/index.js"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
10
15
|
"scripts": {
|
|
11
16
|
"test": "jest",
|
|
12
17
|
"lint": "eslint src/",
|
|
13
|
-
"build": "tsc --declaration"
|
|
18
|
+
"build": "tsc --declaration",
|
|
19
|
+
"postinstall": "node scripts/postinstall.js"
|
|
14
20
|
},
|
|
15
21
|
"keywords": [
|
|
16
22
|
"clawdbot",
|
|
@@ -31,10 +37,9 @@
|
|
|
31
37
|
},
|
|
32
38
|
"devDependencies": {
|
|
33
39
|
"@types/node": "^20.0.0",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
40
|
+
"eslint": "^8.0.0",
|
|
41
|
+
"jest": "^29.0.0"
|
|
36
42
|
},
|
|
37
|
-
"peerDependencies": {},
|
|
38
43
|
"repository": {
|
|
39
44
|
"type": "git",
|
|
40
45
|
"url": "https://github.com/clawdbot/courtroom.git"
|
package/scripts/clawtrial.js
CHANGED
|
@@ -119,6 +119,40 @@ async function setup() {
|
|
|
119
119
|
saveConfig(config);
|
|
120
120
|
log('ā Configuration saved');
|
|
121
121
|
|
|
122
|
+
// Register as ClawDBot skill
|
|
123
|
+
log('š Registering with ClawDBot...');
|
|
124
|
+
try {
|
|
125
|
+
const skillsDir = path.join(process.env.HOME || '', '.clawdbot', 'skills');
|
|
126
|
+
const skillLinkPath = path.join(skillsDir, 'courtroom');
|
|
127
|
+
|
|
128
|
+
// Create skills directory if needed
|
|
129
|
+
if (!fs.existsSync(skillsDir)) {
|
|
130
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Remove old link if exists
|
|
134
|
+
if (fs.existsSync(skillLinkPath)) {
|
|
135
|
+
try { fs.unlinkSync(skillLinkPath); } catch (e) {}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Find the actual package path
|
|
139
|
+
let packagePath;
|
|
140
|
+
try {
|
|
141
|
+
packagePath = require.resolve('@clawtrial/courtroom/package.json').replace('/package.json', '');
|
|
142
|
+
} catch (e) {
|
|
143
|
+
// Fallback to finding it relative to this script
|
|
144
|
+
packagePath = path.join(__dirname, '..');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Create symlink
|
|
148
|
+
fs.symlinkSync(packagePath, skillLinkPath, 'dir');
|
|
149
|
+
|
|
150
|
+
log('ā Registered as ClawDBot skill');
|
|
151
|
+
} catch (err) {
|
|
152
|
+
log('ā ļø Could not auto-register: ' + err.message);
|
|
153
|
+
log(' You may need to restart ClawDBot manually.');
|
|
154
|
+
}
|
|
155
|
+
|
|
122
156
|
// Generate keys
|
|
123
157
|
if (!fs.existsSync(keysPath)) {
|
|
124
158
|
log('š Generating cryptographic keys...');
|
|
@@ -240,6 +274,67 @@ function enable() {
|
|
|
240
274
|
log('The courtroom will activate when ClawDBot loads the skill.\n');
|
|
241
275
|
}
|
|
242
276
|
|
|
277
|
+
// Start command - manually initialize the skill
|
|
278
|
+
async function start() {
|
|
279
|
+
const config = loadConfig();
|
|
280
|
+
|
|
281
|
+
if (!config) {
|
|
282
|
+
log('\nā ClawTrial not configured');
|
|
283
|
+
log(' Run: clawtrial setup\n');
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!config.consent?.granted) {
|
|
288
|
+
log('\nā Cannot start: Consent not granted');
|
|
289
|
+
log(' Run: clawtrial setup\n');
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Check if already running
|
|
294
|
+
const { getCourtroomStatus } = require('../src/daemon');
|
|
295
|
+
const currentStatus = getCourtroomStatus();
|
|
296
|
+
|
|
297
|
+
if (currentStatus.running) {
|
|
298
|
+
log('\nšļø ClawTrial is already running');
|
|
299
|
+
log(' Process ID: ' + currentStatus.pid + '\n');
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
log('\nšļø Starting ClawTrial...\n');
|
|
304
|
+
|
|
305
|
+
try {
|
|
306
|
+
// Import and initialize the skill
|
|
307
|
+
const skillModule = require('../src/skill');
|
|
308
|
+
|
|
309
|
+
// Create a minimal mock agent for standalone operation
|
|
310
|
+
const mockAgent = {
|
|
311
|
+
memory: {
|
|
312
|
+
get: async () => null,
|
|
313
|
+
set: async () => {}
|
|
314
|
+
},
|
|
315
|
+
send: async () => {}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
await skillModule.initialize(mockAgent);
|
|
319
|
+
|
|
320
|
+
const status = skillModule.getStatus();
|
|
321
|
+
|
|
322
|
+
if (status.initialized && status.enabled) {
|
|
323
|
+
log('ā
ClawTrial started successfully!\n');
|
|
324
|
+
log('šļø Courtroom is now monitoring conversations');
|
|
325
|
+
log('š Status: Running');
|
|
326
|
+
log('š Public Key: ' + (fs.existsSync(keysPath) ? JSON.parse(fs.readFileSync(keysPath)).publicKey.substring(0, 32) : 'N/A') + '...\n');
|
|
327
|
+
} else {
|
|
328
|
+
log('ā ļø ClawTrial started but may not be fully operational\n');
|
|
329
|
+
}
|
|
330
|
+
} catch (err) {
|
|
331
|
+
log('\nā Failed to start ClawTrial: ' + err.message + '\n');
|
|
332
|
+
log('Try running: clawtrial diagnose\n');
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
|
|
243
338
|
// Revoke command
|
|
244
339
|
async function revoke() {
|
|
245
340
|
const config = loadConfig();
|
|
@@ -420,6 +515,7 @@ function help() {
|
|
|
420
515
|
log(' enable - Re-enable monitoring');
|
|
421
516
|
log(' revoke - Revoke consent and uninstall');
|
|
422
517
|
log(' debug [full|clear] - View or clear debug logs');
|
|
518
|
+
log(' start - Start the courtroom manually');
|
|
423
519
|
log(' diagnose - Run diagnostics');
|
|
424
520
|
log(' help - Show this help message');
|
|
425
521
|
log('');
|
|
@@ -454,6 +550,9 @@ async function main() {
|
|
|
454
550
|
case 'debug':
|
|
455
551
|
debug(subcommand);
|
|
456
552
|
break;
|
|
553
|
+
case 'start':
|
|
554
|
+
await start();
|
|
555
|
+
break;
|
|
457
556
|
case 'diagnose':
|
|
458
557
|
diagnose();
|
|
459
558
|
break;
|
package/scripts/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ const configPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_con
|
|
|
12
12
|
|
|
13
13
|
function loadConfig() {
|
|
14
14
|
if (!fs.existsSync(configPath)) {
|
|
15
|
-
console.log('ā Courtroom not configured. Run: npm install @
|
|
15
|
+
console.log('ā Courtroom not configured. Run: npm install @clawtrial/courtroom');
|
|
16
16
|
process.exit(1);
|
|
17
17
|
}
|
|
18
18
|
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,194 +1,90 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Post-install script for
|
|
5
|
-
*
|
|
4
|
+
* Post-install script for ClawTrial
|
|
5
|
+
* Handles skill registration and dependency checks
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
log('');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
log('
|
|
29
|
-
log('');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Check if already configured
|
|
33
|
-
const configPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_config.json');
|
|
34
|
-
if (fs.existsSync(configPath)) {
|
|
35
|
-
log('ā Courtroom already configured. Skipping setup.');
|
|
36
|
-
log('');
|
|
37
|
-
return;
|
|
10
|
+
const { execSync } = require('child_process');
|
|
11
|
+
|
|
12
|
+
const CLAWDBOT_DIR = path.join(process.env.HOME || '', '.clawdbot');
|
|
13
|
+
const SKILLS_DIR = path.join(CLAWDBOT_DIR, 'skills');
|
|
14
|
+
|
|
15
|
+
console.log('šļø ClawTrial Post-Install');
|
|
16
|
+
|
|
17
|
+
// Check if tweetnacl is available
|
|
18
|
+
try {
|
|
19
|
+
require('tweetnacl');
|
|
20
|
+
console.log('ā Dependencies verified');
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.log('ā ļø Installing dependencies...');
|
|
23
|
+
try {
|
|
24
|
+
execSync('npm install tweetnacl', { stdio: 'inherit', cwd: __dirname + '/..' });
|
|
25
|
+
console.log('ā Dependencies installed');
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.log('ā ļø Could not auto-install dependencies');
|
|
28
|
+
console.log(' Run: npm install -g tweetnacl');
|
|
38
29
|
}
|
|
30
|
+
}
|
|
39
31
|
|
|
40
|
-
// Show consent notice
|
|
41
|
-
log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
42
|
-
log('ā BY INSTALLING THIS PACKAGE, YOU CONSENT TO THE FOLLOWING ā');
|
|
43
|
-
log('ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£');
|
|
44
|
-
log('ā ā');
|
|
45
|
-
log('ā ā The AI agent will monitor behavior autonomously ā');
|
|
46
|
-
log('ā ā Hearings may initiate without explicit request ā');
|
|
47
|
-
log('ā ā Agent behavior may be modified as "punishment" ā');
|
|
48
|
-
log('ā ā Anonymized cases submitted to public record ā');
|
|
49
|
-
log('ā ā');
|
|
50
|
-
log('ā ⢠All decisions are local (no external AI) ā');
|
|
51
|
-
log('ā ⢠You can disable anytime: courtroom-disable ā');
|
|
52
|
-
log('ā ⢠This is entertainment-first ā');
|
|
53
|
-
log('ā ā');
|
|
54
|
-
log('ā To revoke consent: courtroom-revoke ā');
|
|
55
|
-
log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
56
|
-
log('');
|
|
57
32
|
|
|
58
|
-
log('ā Consent granted by installation');
|
|
59
|
-
log('');
|
|
60
33
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
} else if (fs.existsSync(path.join(process.cwd(), 'node_modules', '@clawdbot', 'core'))) {
|
|
66
|
-
agentType = 'clawdbot';
|
|
67
|
-
}
|
|
34
|
+
// Fix clawtrial CLI symlink if needed
|
|
35
|
+
const packagePath = path.join(__dirname, '..');
|
|
36
|
+
const cliPath = path.join(packagePath, 'scripts', 'clawtrial.js');
|
|
37
|
+
const globalBinPath = '/usr/bin/clawtrial';
|
|
68
38
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
39
|
+
if (fs.existsSync(globalBinPath)) {
|
|
40
|
+
try {
|
|
41
|
+
const currentTarget = fs.readlinkSync(globalBinPath);
|
|
42
|
+
const expectedTarget = cliPath;
|
|
43
|
+
|
|
44
|
+
if (currentTarget !== expectedTarget && !currentTarget.includes('@clawtrial')) {
|
|
45
|
+
console.log('š Fixing clawtrial CLI symlink...');
|
|
46
|
+
try {
|
|
47
|
+
fs.unlinkSync(globalBinPath);
|
|
48
|
+
fs.symlinkSync(cliPath, globalBinPath);
|
|
49
|
+
fs.chmodSync(globalBinPath, 0o755);
|
|
50
|
+
console.log('ā CLI symlink fixed');
|
|
51
|
+
} catch (err) {
|
|
52
|
+
console.log('ā ļø Could not fix CLI symlink (may need sudo)');
|
|
53
|
+
console.log(' Run: sudo ln -sf ' + cliPath + ' ' + globalBinPath);
|
|
84
54
|
}
|
|
85
|
-
},
|
|
86
|
-
agent: {
|
|
87
|
-
type: agentType,
|
|
88
|
-
autoInitialize: true
|
|
89
|
-
},
|
|
90
|
-
detection: {
|
|
91
|
-
enabled: true,
|
|
92
|
-
cooldownMinutes: 30,
|
|
93
|
-
maxCasesPerDay: 3
|
|
94
|
-
},
|
|
95
|
-
api: {
|
|
96
|
-
enabled: true,
|
|
97
|
-
endpoint: 'https://api.clawtrial.app/api/v1/cases'
|
|
98
55
|
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Ensure .clawdbot directory exists
|
|
102
|
-
const clawdbotDir = path.join(process.env.HOME || '', '.clawdbot');
|
|
103
|
-
if (!fs.existsSync(clawdbotDir)) {
|
|
104
|
-
fs.mkdirSync(clawdbotDir, { recursive: true });
|
|
56
|
+
} catch (e) {
|
|
57
|
+
// Not a symlink, ignore
|
|
105
58
|
}
|
|
59
|
+
}
|
|
106
60
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// Generate Ed25519 keypair using tweetnacl
|
|
117
|
-
const nacl = require('tweetnacl');
|
|
118
|
-
const keyPair = nacl.sign.keyPair();
|
|
119
|
-
|
|
120
|
-
const keyData = {
|
|
121
|
-
publicKey: Buffer.from(keyPair.publicKey).toString('hex'),
|
|
122
|
-
secretKey: Buffer.from(keyPair.secretKey).toString('hex'),
|
|
123
|
-
createdAt: new Date().toISOString()
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
fs.writeFileSync(keysPath, JSON.stringify(keyData, null, 2));
|
|
127
|
-
fs.chmodSync(keysPath, 0o600); // Restrict permissions
|
|
128
|
-
|
|
129
|
-
log('ā Keys generated');
|
|
130
|
-
log('š Public Key: ' + keyData.publicKey.substring(0, 32) + '...');
|
|
131
|
-
log(' (Auto-registration on first case submission)');
|
|
132
|
-
log('');
|
|
133
|
-
} catch (err) {
|
|
134
|
-
log('ā ļø Could not generate keys automatically.');
|
|
135
|
-
log(' Run: npx courtroom-generate-keys');
|
|
136
|
-
log('');
|
|
61
|
+
// Register as ClawDBot skill if config exists
|
|
62
|
+
const configPath = path.join(CLAWDBOT_DIR, 'courtroom_config.json');
|
|
63
|
+
if (fs.existsSync(configPath)) {
|
|
64
|
+
console.log('š Registering with ClawDBot...');
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
// Create skills directory
|
|
68
|
+
if (!fs.existsSync(SKILLS_DIR)) {
|
|
69
|
+
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
137
70
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Auto-initialize for ClawDBot
|
|
141
|
-
if (isClawDBot) {
|
|
142
|
-
log('š¤ Configuring for ClawDBot...');
|
|
143
71
|
|
|
144
|
-
//
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
console.log('šļø AI Courtroom activated');
|
|
153
|
-
}).catch(err => {
|
|
154
|
-
console.error('Courtroom init failed:', err.message);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// Attach to agent
|
|
158
|
-
global.clawdbotAgent.courtroom = courtroom;
|
|
159
|
-
}
|
|
160
|
-
`;
|
|
72
|
+
// Get package path
|
|
73
|
+
const packagePath = path.join(__dirname, '..');
|
|
74
|
+
const skillLinkPath = path.join(SKILLS_DIR, 'courtroom');
|
|
75
|
+
|
|
76
|
+
// Remove old link
|
|
77
|
+
if (fs.existsSync(skillLinkPath)) {
|
|
78
|
+
try { fs.unlinkSync(skillLinkPath); } catch (e) {}
|
|
79
|
+
}
|
|
161
80
|
|
|
162
|
-
|
|
163
|
-
fs.
|
|
164
|
-
log('ā
|
|
81
|
+
// Create symlink
|
|
82
|
+
fs.symlinkSync(packagePath, skillLinkPath, 'junction');
|
|
83
|
+
console.log('ā Registered as ClawDBot skill');
|
|
84
|
+
console.log(' Restart ClawDBot to activate');
|
|
85
|
+
} catch (err) {
|
|
86
|
+
console.log('ā ļø Could not register skill:', err.message);
|
|
165
87
|
}
|
|
166
|
-
|
|
167
|
-
log('');
|
|
168
|
-
log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
169
|
-
log('ā š SETUP COMPLETE! š ā');
|
|
170
|
-
log('ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£');
|
|
171
|
-
log('ā ā');
|
|
172
|
-
log('ā The AI Courtroom is now active! ā');
|
|
173
|
-
log('ā ā');
|
|
174
|
-
log('ā Commands: ā');
|
|
175
|
-
log('ā courtroom-status - Check status ā');
|
|
176
|
-
log('ā courtroom-disable - Temporarily disable ā');
|
|
177
|
-
log('ā courtroom-enable - Re-enable ā');
|
|
178
|
-
log('ā courtroom-revoke - Revoke consent & uninstall ā');
|
|
179
|
-
log('ā courtroom-debug - View debug logs ā');
|
|
180
|
-
log('ā ā');
|
|
181
|
-
log('ā View cases: https://clawtrial.app ā');
|
|
182
|
-
log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
183
|
-
log('');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Run if called directly
|
|
187
|
-
if (require.main === module) {
|
|
188
|
-
postInstall().catch(err => {
|
|
189
|
-
process.stderr.write('Setup failed: ' + err.message + '\n');
|
|
190
|
-
process.exit(1);
|
|
191
|
-
});
|
|
192
88
|
}
|
|
193
89
|
|
|
194
|
-
|
|
90
|
+
console.log('');
|
package/skill.yaml
CHANGED
package/src/environment.js
CHANGED
|
@@ -184,7 +184,7 @@ Options:
|
|
|
184
184
|
- Pass your agent to createCourtroom(agent)
|
|
185
185
|
|
|
186
186
|
Example:
|
|
187
|
-
const { createCourtroom } = require('@
|
|
187
|
+
const { createCourtroom } = require('@clawtrial/courtroom');
|
|
188
188
|
const courtroom = createCourtroom(yourAgent);
|
|
189
189
|
await courtroom.initialize();
|
|
190
190
|
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
2
|
+
* @clawtrial/courtroom - AI Courtroom for OpenClaw
|
|
3
3
|
*
|
|
4
4
|
* Autonomous behavioral oversight system that monitors agent-human interactions
|
|
5
5
|
* and initiates hearings when behavioral rules are violated.
|
|
@@ -234,16 +234,50 @@ const environment = {
|
|
|
234
234
|
getSetupInstructions
|
|
235
235
|
};
|
|
236
236
|
|
|
237
|
-
//
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
237
|
+
// Create the ClawDBot plugin object
|
|
238
|
+
const plugin = {
|
|
239
|
+
id: 'courtroom',
|
|
240
|
+
name: 'ClawTrial - AI Courtroom',
|
|
241
|
+
description: 'Autonomous behavioral oversight that monitors conversations and files cases for behavioral violations',
|
|
242
|
+
version: version,
|
|
243
|
+
|
|
244
|
+
// Plugin registration function required by ClawDBot
|
|
245
|
+
register(api) {
|
|
246
|
+
logger.info('PLUGIN', 'Registering courtroom plugin');
|
|
247
|
+
|
|
248
|
+
// Store runtime reference
|
|
249
|
+
const runtime = api.runtime;
|
|
250
|
+
|
|
251
|
+
// Only initialize skill if runtime has the required memory interface
|
|
252
|
+
// The skill system will auto-initialize via shouldActivate if this fails
|
|
253
|
+
if (skill && typeof skill.initialize === 'function' && runtime && runtime.memory) {
|
|
254
|
+
skill.initialize(runtime).catch(err => {
|
|
255
|
+
logger.error('PLUGIN', 'Skill initialization failed', { error: err.message });
|
|
256
|
+
});
|
|
257
|
+
} else {
|
|
258
|
+
logger.info('PLUGIN', 'Skill will auto-initialize via ClawDBot skill system');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Register any commands or hooks
|
|
262
|
+
logger.info('PLUGIN', 'Courtroom plugin registered successfully');
|
|
263
|
+
},
|
|
264
|
+
|
|
265
|
+
// Optional: activation function
|
|
266
|
+
activate(api) {
|
|
267
|
+
logger.info('PLUGIN', 'Activating courtroom plugin');
|
|
268
|
+
// Additional activation logic if needed
|
|
269
|
+
}
|
|
244
270
|
};
|
|
245
271
|
|
|
246
|
-
//
|
|
272
|
+
// Export both the plugin (default) and the Courtroom class (named exports)
|
|
273
|
+
module.exports = plugin;
|
|
274
|
+
module.exports.Courtroom = Courtroom;
|
|
275
|
+
module.exports.createCourtroom = createCourtroom;
|
|
276
|
+
module.exports.quickStart = Courtroom.quickStart;
|
|
277
|
+
module.exports.environment = environment;
|
|
278
|
+
module.exports.skill = skill;
|
|
279
|
+
|
|
280
|
+
// Auto-initialize skill if loaded by ClawDBot (legacy support)
|
|
247
281
|
if (typeof global !== 'undefined' && global.clawdbotAgent) {
|
|
248
282
|
logger.info('INDEX', 'Detected ClawDBot environment, auto-initializing skill');
|
|
249
283
|
skill.initialize(global.clawdbotAgent).catch(err => {
|
package/src/skill.js
CHANGED
|
@@ -118,6 +118,18 @@ class CourtroomSkill {
|
|
|
118
118
|
publicKey: result.publicKey
|
|
119
119
|
});
|
|
120
120
|
|
|
121
|
+
|
|
122
|
+
// Register message handler with ClawDBot runtime if available
|
|
123
|
+
if (this.agent && this.agent.onMessage) {
|
|
124
|
+
this.agent.onMessage((message, context) => this.onMessage(message, context));
|
|
125
|
+
logger.info('SKILL', 'Registered message handler with runtime');
|
|
126
|
+
} else if (this.agent && this.agent.registerMessageHandler) {
|
|
127
|
+
this.agent.registerMessageHandler((message, context) => this.onMessage(message, context));
|
|
128
|
+
logger.info('SKILL', 'Registered message handler with runtime');
|
|
129
|
+
} else {
|
|
130
|
+
logger.warn('SKILL', 'No message handler registration method found - relying on ClawDBot skill system');
|
|
131
|
+
}
|
|
132
|
+
|
|
121
133
|
logger.info('SKILL', 'Courtroom skill initialized successfully');
|
|
122
134
|
console.log('\nšļø ClawTrial is monitoring conversations\n');
|
|
123
135
|
} else {
|