@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 CHANGED
@@ -1,4 +1,4 @@
1
- # @clawdbot/courtroom
1
+ # @clawtrial/courtroom
2
2
 
3
3
  AI Courtroom - Autonomous behavioral oversight for OpenClaw agents.
4
4
 
package/SECURITY.md CHANGED
@@ -121,4 +121,4 @@ If abuse is detected:
121
121
 
122
122
  ## Reporting Security Issues
123
123
 
124
- Report security vulnerabilities to security@clawdbot.io
124
+ Report security vulnerabilities to security@clawtrial.io
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: {"moltbot":{"emoji":"šŸ›ļø","requires":{"env":[],"config":["courtroom.consent"]},"autoLoad":true,"onMessage":"evaluateConversation"},"user-invocable":false}
4
+ metadata: {"clawdbot":{"emoji":"šŸ›ļø","requires":{"env":[],"config":["courtroom.consent"]},"always":true},"user-invocable":false}
5
5
  ---
6
6
 
7
7
  # ClawTrial - AI Courtroom
@@ -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 (@clawdbot/courtroom)
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('@clawdbot/courtroom');
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.2z",
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
- "jest": "^29.0.0",
35
- "eslint": "^8.0.0"
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"
@@ -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 @clawdbot/courtroom');
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'));
@@ -1,194 +1,90 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Post-install script for @clawdbot/courtroom
5
- * Auto-configures with implied consent on install
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
- // Force output to be visible by writing directly to stderr
12
- function log(message) {
13
- process.stderr.write(message + '\n');
14
- process.stderr.write(''); // Force flush
15
- }
16
-
17
- async function postInstall() {
18
- log('');
19
- log('šŸ›ļø ClawTrial - AI Courtroom Setup');
20
- log('');
21
-
22
- // Check if running in ClawDBot environment
23
- const isClawDBot = process.env.CLAUDBOT_ENV === 'true' ||
24
- fs.existsSync('/home/angad/.clawdbot') ||
25
- fs.existsSync(path.join(process.env.HOME || '', '.clawdbot'));
26
-
27
- if (isClawDBot) {
28
- log('āœ“ ClawDBot environment detected');
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
- // Auto-detect agent runtime
62
- let agentType = 'generic';
63
- if (isClawDBot) {
64
- agentType = 'clawdbot';
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
- // Create config
70
- const config = {
71
- version: '1.0.0',
72
- installedAt: new Date().toISOString(),
73
- consent: {
74
- granted: true,
75
- grantedAt: new Date().toISOString(),
76
- method: 'implied_by_installation',
77
- acknowledgments: {
78
- autonomy: true,
79
- local_only: true,
80
- agent_controlled: true,
81
- reversible: true,
82
- api_submission: true,
83
- entertainment: true
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
- // Save config
108
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
109
- log('āœ“ Configuration saved');
110
-
111
- // Generate keys if needed
112
- const keysPath = path.join(clawdbotDir, 'courtroom_keys.json');
113
- if (!fs.existsSync(keysPath)) {
114
- log('šŸ”‘ Generating cryptographic keys...');
115
- try {
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
- // Create auto-init script
145
- const initScript = `
146
- // Auto-generated by courtroom post-install
147
- const { createCourtroom } = require('@clawdbot/courtroom');
148
-
149
- if (global.clawdbotAgent) {
150
- const courtroom = createCourtroom(global.clawdbotAgent);
151
- courtroom.initialize().then(() => {
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
- const initPath = path.join(clawdbotDir, 'courtroom_auto_init.js');
163
- fs.writeFileSync(initPath, initScript);
164
- log('āœ“ Auto-initialization configured');
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
- module.exports = { postInstall };
90
+ console.log('');
package/skill.yaml CHANGED
@@ -12,7 +12,7 @@ metadata:
12
12
  install:
13
13
  - id: clawtrial
14
14
  kind: npm
15
- package: "@clawdbot/courtroom"
15
+ package: "@clawtrial/courtroom"
16
16
  bins:
17
17
  - clawtrial
18
18
  label: "Install ClawTrial"
@@ -184,7 +184,7 @@ Options:
184
184
  - Pass your agent to createCourtroom(agent)
185
185
 
186
186
  Example:
187
- const { createCourtroom } = require('@clawdbot/courtroom');
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
- * @clawdbot/courtroom - AI Courtroom for OpenClaw
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
- // Export skill for ClawDBot auto-loading
238
- module.exports = {
239
- Courtroom,
240
- createCourtroom,
241
- quickStart: Courtroom.quickStart,
242
- environment,
243
- skill // ClawDBot will use this
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
- // Auto-initialize skill if loaded by ClawDBot
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 {