@clawtrial/courtroom 1.0.2 → 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.
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * ClawTrial CLI - Main entry point
4
+ * ClawTrial CLI - Configuration and status tool
5
5
  * Usage: clawtrial <command> [options]
6
+ *
7
+ * Note: The courtroom runs as a ClawDBot skill, not a separate process.
8
+ * This CLI is for configuration and status checking only.
6
9
  */
7
10
 
8
11
  const fs = require('fs');
@@ -41,15 +44,10 @@ async function setup() {
41
44
  log('✓ Courtroom already configured');
42
45
  log(` Installed: ${new Date(config.installedAt).toLocaleDateString()}`);
43
46
  log(` Status: ${config.enabled !== false ? 'Active' : 'Disabled'}`);
44
- log('\nTo reconfigure, first run: clawtrial revoke\n');
47
+ log('\nThe courtroom will activate when ClawDBot loads the skill.\n');
45
48
  return;
46
49
  }
47
50
 
48
- // Check if ClawDBot environment
49
- const isClawDBot = process.env.CLAUDBOT_ENV === 'true' ||
50
- fs.existsSync('/home/angad/.clawdbot') ||
51
- fs.existsSync(path.join(process.env.HOME || '', '.clawdbot'));
52
-
53
51
  // Show consent notice
54
52
  log('╔════════════════════════════════════════════════════════════╗');
55
53
  log('║ BY SETTING UP CLAWTRIAL, YOU CONSENT TO THE FOLLOWING ║');
@@ -86,13 +84,6 @@ async function setup() {
86
84
 
87
85
  log('\n✓ Consent granted\n');
88
86
 
89
- // Auto-detect agent runtime
90
- let agentType = 'generic';
91
- if (isClawDBot) {
92
- agentType = 'clawdbot';
93
- log('✓ ClawDBot environment detected');
94
- }
95
-
96
87
  // Create config
97
88
  const config = {
98
89
  version: '1.0.0',
@@ -111,7 +102,7 @@ async function setup() {
111
102
  }
112
103
  },
113
104
  agent: {
114
- type: agentType,
105
+ type: 'clawdbot',
115
106
  autoInitialize: true
116
107
  },
117
108
  detection: {
@@ -128,6 +119,40 @@ async function setup() {
128
119
  saveConfig(config);
129
120
  log('✓ Configuration saved');
130
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
+
131
156
  // Generate keys
132
157
  if (!fs.existsSync(keysPath)) {
133
158
  log('🔑 Generating cryptographic keys...');
@@ -151,32 +176,14 @@ async function setup() {
151
176
  }
152
177
  }
153
178
 
154
- // Create auto-init script for ClawDBot
155
- if (isClawDBot) {
156
- const clawdbotDir = path.join(process.env.HOME || '', '.clawdbot');
157
- const initScript = `
158
- // Auto-generated by ClawTrial setup
159
- const { createCourtroom } = require('@clawdbot/courtroom');
160
-
161
- if (global.clawdbotAgent) {
162
- const courtroom = createCourtroom(global.clawdbotAgent);
163
- courtroom.initialize().then(() => {
164
- console.log('🏛️ ClawTrial activated');
165
- }).catch(err => {
166
- console.error('ClawTrial init failed:', err.message);
167
- });
168
- global.clawdbotAgent.courtroom = courtroom;
169
- }
170
- `;
171
- fs.writeFileSync(path.join(clawdbotDir, 'courtroom_auto_init.js'), initScript);
172
- log('✓ Auto-initialization configured');
173
- }
174
-
175
179
  log('\n╔════════════════════════════════════════════════════════════╗');
176
180
  log('║ 🎉 SETUP COMPLETE! 🎉 ║');
177
181
  log('╠════════════════════════════════════════════════════════════╣');
178
182
  log('║ ║');
179
- log('║ ClawTrial is now active and monitoring! ║');
183
+ log('║ ClawTrial is configured and ready! ║');
184
+ log('║ ║');
185
+ log('║ The courtroom will automatically activate when ║');
186
+ log('║ ClawDBot loads the skill. ║');
180
187
  log('║ ║');
181
188
  log('║ Commands: ║');
182
189
  log('║ clawtrial status - Check status ║');
@@ -184,6 +191,7 @@ if (global.clawdbotAgent) {
184
191
  log('║ clawtrial enable - Re-enable ║');
185
192
  log('║ clawtrial revoke - Revoke consent & uninstall ║');
186
193
  log('║ clawtrial debug - View debug logs ║');
194
+ log('║ clawtrial diagnose - Run diagnostics ║');
187
195
  log('║ ║');
188
196
  log('║ View cases: https://clawtrial.app ║');
189
197
  log('╚════════════════════════════════════════════════════════════╝\n');
@@ -199,18 +207,31 @@ function status() {
199
207
  return;
200
208
  }
201
209
 
210
+ // Check if courtroom is running via status file
211
+ const { getCourtroomStatus } = require('../src/daemon');
212
+ const runtimeStatus = getCourtroomStatus();
213
+
202
214
  log('\n🏛️ ClawTrial Status\n');
203
- log(`Status: ${config.enabled !== false ? '✅ Active' : '⏸️ Disabled'}`);
215
+ log(`Config: ${config.enabled !== false ? '✅ Active' : '⏸️ Disabled'}`);
204
216
  log(`Consent: ${config.consent?.granted ? '✅ Granted' : '❌ Not granted'}`);
205
217
  log(`Installed: ${new Date(config.installedAt).toLocaleDateString()}`);
206
- log(`Agent Type: ${config.agent?.type || 'generic'}`);
207
- log(`Detection: ${config.detection?.enabled ? '✅ Enabled' : '❌ Disabled'}`);
208
- log(`API Submission: ${config.api?.enabled ? 'Enabled' : '❌ Disabled'}`);
209
- log(`Endpoint: ${config.api?.endpoint || 'Not set'}`);
218
+
219
+ if (runtimeStatus.running) {
220
+ log(`\n🏛️ Courtroom: ✅ Running`);
221
+ log(` Process ID: ${runtimeStatus.pid}`);
222
+ log(` Cases Filed: ${runtimeStatus.casesFiled || 0}`);
223
+ if (runtimeStatus.lastCase) {
224
+ log(` Last Case: ${new Date(runtimeStatus.lastCase.timestamp).toLocaleString()}`);
225
+ }
226
+ } else {
227
+ log(`\n🏛️ Courtroom: ⏸️ Not running`);
228
+ log(' The courtroom runs as a ClawDBot skill.');
229
+ log(' It will activate when ClawDBot loads the package.');
230
+ }
210
231
 
211
232
  if (fs.existsSync(keysPath)) {
212
233
  const keys = JSON.parse(fs.readFileSync(keysPath, 'utf8'));
213
- log(`Public Key: ${keys.publicKey.substring(0, 32)}...`);
234
+ log(`\n📋 Public Key: ${keys.publicKey.substring(0, 32)}...`);
214
235
  }
215
236
  log('');
216
237
  }
@@ -250,9 +271,70 @@ function enable() {
250
271
  config.enabled = true;
251
272
  saveConfig(config);
252
273
  log('\n✅ ClawTrial enabled\n');
253
- log('The agent is now monitoring for behavioral violations.\n');
274
+ log('The courtroom will activate when ClawDBot loads the skill.\n');
254
275
  }
255
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
+
256
338
  // Revoke command
257
339
  async function revoke() {
258
340
  const config = loadConfig();
@@ -283,8 +365,8 @@ async function revoke() {
283
365
  const debugPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_debug.log');
284
366
  if (fs.existsSync(debugPath)) fs.unlinkSync(debugPath);
285
367
 
286
- const initPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_auto_init.js');
287
- if (fs.existsSync(initPath)) fs.unlinkSync(initPath);
368
+ const statusPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_status.json');
369
+ if (fs.existsSync(statusPath)) fs.unlinkSync(statusPath);
288
370
 
289
371
  log('\n✅ Consent revoked and all data deleted.\n');
290
372
  } else {
@@ -347,6 +429,81 @@ function debug(subcommand) {
347
429
  }
348
430
  }
349
431
 
432
+ // Diagnose command
433
+ function diagnose() {
434
+ log('\n🏛️ ClawTrial Diagnostics\n');
435
+ log('========================\n');
436
+
437
+ // Check Node version
438
+ const nodeVersion = process.version;
439
+ const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0]);
440
+ log(`Node.js version: ${nodeVersion} ${majorVersion >= 18 ? '✅' : '❌ (needs >= 18)'}`);
441
+
442
+ // Check environment
443
+ const { checkEnvironment } = require('../src/environment');
444
+ const env = checkEnvironment();
445
+ log(`\nEnvironment: ${env.valid ? '✅ Valid' : '❌ Issues found'}`);
446
+ if (!env.valid) {
447
+ env.issues.forEach(issue => log(` ❌ ${issue}`));
448
+ }
449
+
450
+ // Check config
451
+ const config = loadConfig();
452
+ if (config) {
453
+ log(`\nConfig: ✅ Found`);
454
+ log(` Installed: ${new Date(config.installedAt).toLocaleDateString()}`);
455
+ log(` Consent: ${config.consent?.granted ? '✅ Granted' : '❌ Not granted'}`);
456
+ log(` Status: ${config.enabled !== false ? '✅ Enabled' : '⏸️ Disabled'}`);
457
+ } else {
458
+ log(`\nConfig: ❌ Not found`);
459
+ log(' Run: clawtrial setup');
460
+ }
461
+
462
+ // Check keys
463
+ if (fs.existsSync(keysPath)) {
464
+ log(`\nKeys: ✅ Found`);
465
+ const keys = JSON.parse(fs.readFileSync(keysPath, 'utf8'));
466
+ log(` Public Key: ${keys.publicKey.substring(0, 32)}...`);
467
+ } else {
468
+ log(`\nKeys: ❌ Not found`);
469
+ }
470
+
471
+ // Check if courtroom is running
472
+ const { getCourtroomStatus } = require('../src/daemon');
473
+ const runtimeStatus = getCourtroomStatus();
474
+
475
+ if (runtimeStatus.running) {
476
+ log(`\n🏛️ Courtroom: ✅ Running`);
477
+ log(` Process ID: ${runtimeStatus.pid}`);
478
+ log(` Started: ${new Date(runtimeStatus.startedAt).toLocaleString()}`);
479
+ log(` Cases Filed: ${runtimeStatus.casesFiled || 0}`);
480
+ } else {
481
+ log(`\n🏛️ Courtroom: ⏸️ Not running`);
482
+ log(' The courtroom runs as a ClawDBot skill.');
483
+ log(' It will activate when ClawDBot loads the package.');
484
+ }
485
+
486
+ // Check debug logs
487
+ const debugPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_debug.log');
488
+ if (fs.existsSync(debugPath)) {
489
+ const logs = fs.readFileSync(debugPath, 'utf8').split('\n').filter(Boolean);
490
+ log(`\nDebug Logs: ✅ ${logs.length} entries`);
491
+ } else {
492
+ log(`\nDebug Logs: ℹ️ None yet (created when active)`);
493
+ }
494
+
495
+ log('\n========================\n');
496
+
497
+ if (!config) {
498
+ log('Next step: Run "clawtrial setup"');
499
+ } else if (!runtimeStatus.running) {
500
+ log('Status: Configured. Courtroom will activate with ClawDBot.');
501
+ } else {
502
+ log('Status: Fully operational! 🎉');
503
+ }
504
+ log('');
505
+ }
506
+
350
507
  // Help command
351
508
  function help() {
352
509
  log('\n🏛️ ClawTrial - AI Courtroom for Agents\n');
@@ -358,12 +515,14 @@ function help() {
358
515
  log(' enable - Re-enable monitoring');
359
516
  log(' revoke - Revoke consent and uninstall');
360
517
  log(' debug [full|clear] - View or clear debug logs');
518
+ log(' start - Start the courtroom manually');
519
+ log(' diagnose - Run diagnostics');
361
520
  log(' help - Show this help message');
362
521
  log('');
363
522
  log('Examples:');
364
523
  log(' clawtrial setup');
365
524
  log(' clawtrial status');
366
- log(' clawtrial debug full');
525
+ log(' clawtrial diagnose');
367
526
  log('');
368
527
  }
369
528
 
@@ -391,6 +550,12 @@ async function main() {
391
550
  case 'debug':
392
551
  debug(subcommand);
393
552
  break;
553
+ case 'start':
554
+ await start();
555
+ break;
556
+ case 'diagnose':
557
+ diagnose();
558
+ break;
394
559
  case 'help':
395
560
  case '--help':
396
561
  case '-h':
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('');