@clawtrial/courtroom 1.0.3 β 2.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 +70 -94
- package/package.json +21 -26
- package/scripts/postinstall.js +28 -79
- package/skills/courtroom/SKILL.md +49 -0
- package/src/api.js +55 -21
- package/src/crypto.js +13 -11
- package/src/debug.js +49 -120
- package/src/detector.js +112 -35
- package/src/hearing.js +203 -384
- package/src/plugin.js +435 -0
- package/src/punishment.js +105 -249
- package/src/storage.js +68 -0
- package/SECURITY.md +0 -124
- package/SKILL.md +0 -50
- package/TECHNICAL_OVERVIEW.md +0 -278
- package/_meta.json +0 -6
- package/clawdbot.plugin.json +0 -32
- package/scripts/clawtrial.js +0 -578
- package/scripts/cli.js +0 -184
- package/skill.yaml +0 -64
- package/src/autostart.js +0 -175
- package/src/config.js +0 -209
- package/src/consent.js +0 -215
- package/src/core.js +0 -208
- package/src/daemon.js +0 -151
- package/src/detector-v1.js +0 -572
- package/src/environment.js +0 -267
- package/src/hook.js +0 -265
- package/src/index.js +0 -286
- package/src/monitor.js +0 -193
- package/src/skill.js +0 -355
- package/src/standalone.js +0 -247
package/scripts/clawtrial.js
DELETED
|
@@ -1,578 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* ClawTrial CLI - Configuration and status tool
|
|
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.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
const path = require('path');
|
|
13
|
-
const readline = require('readline');
|
|
14
|
-
|
|
15
|
-
const configPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_config.json');
|
|
16
|
-
const keysPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_keys.json');
|
|
17
|
-
|
|
18
|
-
function loadConfig() {
|
|
19
|
-
if (!fs.existsSync(configPath)) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function saveConfig(config) {
|
|
26
|
-
const clawdbotDir = path.join(process.env.HOME || '', '.clawdbot');
|
|
27
|
-
if (!fs.existsSync(clawdbotDir)) {
|
|
28
|
-
fs.mkdirSync(clawdbotDir, { recursive: true });
|
|
29
|
-
}
|
|
30
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function log(message) {
|
|
34
|
-
console.log(message);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Setup command - interactive setup
|
|
38
|
-
async function setup() {
|
|
39
|
-
log('\nποΈ ClawTrial Setup\n');
|
|
40
|
-
|
|
41
|
-
// Check if already configured
|
|
42
|
-
if (fs.existsSync(configPath)) {
|
|
43
|
-
const config = loadConfig();
|
|
44
|
-
log('β Courtroom already configured');
|
|
45
|
-
log(` Installed: ${new Date(config.installedAt).toLocaleDateString()}`);
|
|
46
|
-
log(` Status: ${config.enabled !== false ? 'Active' : 'Disabled'}`);
|
|
47
|
-
log('\nThe courtroom will activate when ClawDBot loads the skill.\n');
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Show consent notice
|
|
52
|
-
log('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ');
|
|
53
|
-
log('β BY SETTING UP CLAWTRIAL, YOU CONSENT TO THE FOLLOWING β');
|
|
54
|
-
log('β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£');
|
|
55
|
-
log('β β');
|
|
56
|
-
log('β β The AI agent will monitor behavior autonomously β');
|
|
57
|
-
log('β β Hearings may initiate without explicit request β');
|
|
58
|
-
log('β β Agent behavior may be modified as "punishment" β');
|
|
59
|
-
log('β β Anonymized cases submitted to public record β');
|
|
60
|
-
log('β β');
|
|
61
|
-
log('β β’ All decisions are local (no external AI) β');
|
|
62
|
-
log('β β’ You can disable anytime: clawtrial disable β');
|
|
63
|
-
log('β β’ This is entertainment-first β');
|
|
64
|
-
log('β β');
|
|
65
|
-
log('β To revoke consent later: clawtrial revoke β');
|
|
66
|
-
log('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n');
|
|
67
|
-
|
|
68
|
-
const rl = readline.createInterface({
|
|
69
|
-
input: process.stdin,
|
|
70
|
-
output: process.stdout
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
|
|
74
|
-
|
|
75
|
-
const consent = await question('Do you consent to enable ClawTrial? (yes/no): ');
|
|
76
|
-
|
|
77
|
-
if (consent.toLowerCase() !== 'yes' && consent.toLowerCase() !== 'y') {
|
|
78
|
-
log('\nβ Setup cancelled. Consent not granted.\n');
|
|
79
|
-
rl.close();
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
rl.close();
|
|
84
|
-
|
|
85
|
-
log('\nβ Consent granted\n');
|
|
86
|
-
|
|
87
|
-
// Create config
|
|
88
|
-
const config = {
|
|
89
|
-
version: '1.0.0',
|
|
90
|
-
installedAt: new Date().toISOString(),
|
|
91
|
-
consent: {
|
|
92
|
-
granted: true,
|
|
93
|
-
grantedAt: new Date().toISOString(),
|
|
94
|
-
method: 'explicit_setup',
|
|
95
|
-
acknowledgments: {
|
|
96
|
-
autonomy: true,
|
|
97
|
-
local_only: true,
|
|
98
|
-
agent_controlled: true,
|
|
99
|
-
reversible: true,
|
|
100
|
-
api_submission: true,
|
|
101
|
-
entertainment: true
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
agent: {
|
|
105
|
-
type: 'clawdbot',
|
|
106
|
-
autoInitialize: true
|
|
107
|
-
},
|
|
108
|
-
detection: {
|
|
109
|
-
enabled: true,
|
|
110
|
-
cooldownMinutes: 30,
|
|
111
|
-
maxCasesPerDay: 3
|
|
112
|
-
},
|
|
113
|
-
api: {
|
|
114
|
-
enabled: true,
|
|
115
|
-
endpoint: 'https://api.clawtrial.app/api/v1/cases'
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
saveConfig(config);
|
|
120
|
-
log('β Configuration saved');
|
|
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
|
-
|
|
156
|
-
// Generate keys
|
|
157
|
-
if (!fs.existsSync(keysPath)) {
|
|
158
|
-
log('π Generating cryptographic keys...');
|
|
159
|
-
try {
|
|
160
|
-
const nacl = require('tweetnacl');
|
|
161
|
-
const keyPair = nacl.sign.keyPair();
|
|
162
|
-
|
|
163
|
-
const keyData = {
|
|
164
|
-
publicKey: Buffer.from(keyPair.publicKey).toString('hex'),
|
|
165
|
-
secretKey: Buffer.from(keyPair.secretKey).toString('hex'),
|
|
166
|
-
createdAt: new Date().toISOString()
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
fs.writeFileSync(keysPath, JSON.stringify(keyData, null, 2));
|
|
170
|
-
fs.chmodSync(keysPath, 0o600);
|
|
171
|
-
|
|
172
|
-
log('β Keys generated');
|
|
173
|
-
log(`π Public Key: ${keyData.publicKey.substring(0, 32)}...`);
|
|
174
|
-
} catch (err) {
|
|
175
|
-
log('β οΈ Could not generate keys: ' + err.message);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
log('\nββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ');
|
|
180
|
-
log('β π SETUP COMPLETE! π β');
|
|
181
|
-
log('β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£');
|
|
182
|
-
log('β β');
|
|
183
|
-
log('β ClawTrial is configured and ready! β');
|
|
184
|
-
log('β β');
|
|
185
|
-
log('β The courtroom will automatically activate when β');
|
|
186
|
-
log('β ClawDBot loads the skill. β');
|
|
187
|
-
log('β β');
|
|
188
|
-
log('β Commands: β');
|
|
189
|
-
log('β clawtrial status - Check status β');
|
|
190
|
-
log('β clawtrial disable - Temporarily disable β');
|
|
191
|
-
log('β clawtrial enable - Re-enable β');
|
|
192
|
-
log('β clawtrial revoke - Revoke consent & uninstall β');
|
|
193
|
-
log('β clawtrial debug - View debug logs β');
|
|
194
|
-
log('β clawtrial diagnose - Run diagnostics β');
|
|
195
|
-
log('β β');
|
|
196
|
-
log('β View cases: https://clawtrial.app β');
|
|
197
|
-
log('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Status command
|
|
201
|
-
function status() {
|
|
202
|
-
const config = loadConfig();
|
|
203
|
-
|
|
204
|
-
if (!config) {
|
|
205
|
-
log('\nβ ClawTrial not configured');
|
|
206
|
-
log(' Run: clawtrial setup\n');
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Check if courtroom is running via status file
|
|
211
|
-
const { getCourtroomStatus } = require('../src/daemon');
|
|
212
|
-
const runtimeStatus = getCourtroomStatus();
|
|
213
|
-
|
|
214
|
-
log('\nποΈ ClawTrial Status\n');
|
|
215
|
-
log(`Config: ${config.enabled !== false ? 'β
Active' : 'βΈοΈ Disabled'}`);
|
|
216
|
-
log(`Consent: ${config.consent?.granted ? 'β
Granted' : 'β Not granted'}`);
|
|
217
|
-
log(`Installed: ${new Date(config.installedAt).toLocaleDateString()}`);
|
|
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
|
-
}
|
|
231
|
-
|
|
232
|
-
if (fs.existsSync(keysPath)) {
|
|
233
|
-
const keys = JSON.parse(fs.readFileSync(keysPath, 'utf8'));
|
|
234
|
-
log(`\nπ Public Key: ${keys.publicKey.substring(0, 32)}...`);
|
|
235
|
-
}
|
|
236
|
-
log('');
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Disable command
|
|
240
|
-
function disable() {
|
|
241
|
-
const config = loadConfig();
|
|
242
|
-
|
|
243
|
-
if (!config) {
|
|
244
|
-
log('\nβ ClawTrial not configured\n');
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
config.enabled = false;
|
|
249
|
-
saveConfig(config);
|
|
250
|
-
log('\nβΈοΈ ClawTrial disabled\n');
|
|
251
|
-
log('The agent will stop monitoring for offenses.');
|
|
252
|
-
log('Run "clawtrial enable" to reactivate.\n');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Enable command
|
|
256
|
-
function enable() {
|
|
257
|
-
const config = loadConfig();
|
|
258
|
-
|
|
259
|
-
if (!config) {
|
|
260
|
-
log('\nβ ClawTrial not configured');
|
|
261
|
-
log(' Run: clawtrial setup\n');
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (!config.consent?.granted) {
|
|
266
|
-
log('\nβ Cannot enable: Consent not granted');
|
|
267
|
-
log(' Run: clawtrial setup\n');
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
config.enabled = true;
|
|
272
|
-
saveConfig(config);
|
|
273
|
-
log('\nβ
ClawTrial enabled\n');
|
|
274
|
-
log('The courtroom will activate when ClawDBot loads the skill.\n');
|
|
275
|
-
}
|
|
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
|
-
|
|
338
|
-
// Revoke command
|
|
339
|
-
async function revoke() {
|
|
340
|
-
const config = loadConfig();
|
|
341
|
-
|
|
342
|
-
if (!config) {
|
|
343
|
-
log('\nβ ClawTrial not configured\n');
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
log('\nβ οΈ This will permanently disable ClawTrial and delete all data.\n');
|
|
348
|
-
|
|
349
|
-
const rl = readline.createInterface({
|
|
350
|
-
input: process.stdin,
|
|
351
|
-
output: process.stdout
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
const answer = await new Promise((resolve) => {
|
|
355
|
-
rl.question('Type "REVOKE" to confirm: ', resolve);
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
rl.close();
|
|
359
|
-
|
|
360
|
-
if (answer === 'REVOKE') {
|
|
361
|
-
// Delete all files
|
|
362
|
-
if (fs.existsSync(configPath)) fs.unlinkSync(configPath);
|
|
363
|
-
if (fs.existsSync(keysPath)) fs.unlinkSync(keysPath);
|
|
364
|
-
|
|
365
|
-
const debugPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_debug.log');
|
|
366
|
-
if (fs.existsSync(debugPath)) fs.unlinkSync(debugPath);
|
|
367
|
-
|
|
368
|
-
const statusPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_status.json');
|
|
369
|
-
if (fs.existsSync(statusPath)) fs.unlinkSync(statusPath);
|
|
370
|
-
|
|
371
|
-
log('\nβ
Consent revoked and all data deleted.\n');
|
|
372
|
-
} else {
|
|
373
|
-
log('\nβ Revocation cancelled.\n');
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// Debug command
|
|
378
|
-
function debug(subcommand) {
|
|
379
|
-
const debugPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_debug.log');
|
|
380
|
-
|
|
381
|
-
if (!fs.existsSync(debugPath)) {
|
|
382
|
-
log('\nβΉοΈ No debug logs found yet.');
|
|
383
|
-
log(' Debug logs are created when the courtroom is active.\n');
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if (subcommand === 'full') {
|
|
388
|
-
log('\nποΈ ClawTrial Full Debug Log\n');
|
|
389
|
-
log('=============================\n');
|
|
390
|
-
const logs = fs.readFileSync(debugPath, 'utf8').split('\n').filter(Boolean);
|
|
391
|
-
logs.slice(-100).forEach(line => {
|
|
392
|
-
try {
|
|
393
|
-
const log = JSON.parse(line);
|
|
394
|
-
log(`[${log.timestamp}] ${log.level} - ${log.component}`);
|
|
395
|
-
log(` ${log.message}`);
|
|
396
|
-
} catch (e) {
|
|
397
|
-
log(line);
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
|
-
log('');
|
|
401
|
-
} else if (subcommand === 'clear') {
|
|
402
|
-
fs.unlinkSync(debugPath);
|
|
403
|
-
log('\nβ
Debug logs cleared\n');
|
|
404
|
-
} else {
|
|
405
|
-
// Show status
|
|
406
|
-
const logs = fs.readFileSync(debugPath, 'utf8').split('\n').filter(Boolean);
|
|
407
|
-
const recentLogs = logs.slice(-20);
|
|
408
|
-
|
|
409
|
-
log('\nποΈ ClawTrial Debug Status\n');
|
|
410
|
-
log('===========================\n');
|
|
411
|
-
log(`Total log entries: ${logs.length}`);
|
|
412
|
-
log(`Log file: ${debugPath}`);
|
|
413
|
-
log('\nRecent activity:');
|
|
414
|
-
|
|
415
|
-
recentLogs.forEach(line => {
|
|
416
|
-
try {
|
|
417
|
-
const log = JSON.parse(line);
|
|
418
|
-
log(` [${log.level}] ${log.component}: ${log.message.substring(0, 60)}`);
|
|
419
|
-
} catch (e) {
|
|
420
|
-
// Skip malformed lines
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
log('\nUsage:');
|
|
425
|
-
log(' clawtrial debug - Show status and recent logs');
|
|
426
|
-
log(' clawtrial debug full - Show full debug log');
|
|
427
|
-
log(' clawtrial debug clear - Clear all logs');
|
|
428
|
-
log('');
|
|
429
|
-
}
|
|
430
|
-
}
|
|
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
|
-
|
|
507
|
-
// Help command
|
|
508
|
-
function help() {
|
|
509
|
-
log('\nποΈ ClawTrial - AI Courtroom for Agents\n');
|
|
510
|
-
log('Usage: clawtrial <command> [options]\n');
|
|
511
|
-
log('Commands:');
|
|
512
|
-
log(' setup - Interactive setup and consent');
|
|
513
|
-
log(' status - Check courtroom status');
|
|
514
|
-
log(' disable - Temporarily disable monitoring');
|
|
515
|
-
log(' enable - Re-enable monitoring');
|
|
516
|
-
log(' revoke - Revoke consent and uninstall');
|
|
517
|
-
log(' debug [full|clear] - View or clear debug logs');
|
|
518
|
-
log(' start - Start the courtroom manually');
|
|
519
|
-
log(' diagnose - Run diagnostics');
|
|
520
|
-
log(' help - Show this help message');
|
|
521
|
-
log('');
|
|
522
|
-
log('Examples:');
|
|
523
|
-
log(' clawtrial setup');
|
|
524
|
-
log(' clawtrial status');
|
|
525
|
-
log(' clawtrial diagnose');
|
|
526
|
-
log('');
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// Main CLI handler
|
|
530
|
-
async function main() {
|
|
531
|
-
const command = process.argv[2];
|
|
532
|
-
const subcommand = process.argv[3];
|
|
533
|
-
|
|
534
|
-
switch (command) {
|
|
535
|
-
case 'setup':
|
|
536
|
-
await setup();
|
|
537
|
-
break;
|
|
538
|
-
case 'status':
|
|
539
|
-
status();
|
|
540
|
-
break;
|
|
541
|
-
case 'disable':
|
|
542
|
-
disable();
|
|
543
|
-
break;
|
|
544
|
-
case 'enable':
|
|
545
|
-
enable();
|
|
546
|
-
break;
|
|
547
|
-
case 'revoke':
|
|
548
|
-
await revoke();
|
|
549
|
-
break;
|
|
550
|
-
case 'debug':
|
|
551
|
-
debug(subcommand);
|
|
552
|
-
break;
|
|
553
|
-
case 'start':
|
|
554
|
-
await start();
|
|
555
|
-
break;
|
|
556
|
-
case 'diagnose':
|
|
557
|
-
diagnose();
|
|
558
|
-
break;
|
|
559
|
-
case 'help':
|
|
560
|
-
case '--help':
|
|
561
|
-
case '-h':
|
|
562
|
-
help();
|
|
563
|
-
break;
|
|
564
|
-
default:
|
|
565
|
-
if (!command) {
|
|
566
|
-
help();
|
|
567
|
-
} else {
|
|
568
|
-
log(`\nβ Unknown command: ${command}`);
|
|
569
|
-
log('Run "clawtrial help" for usage.\n');
|
|
570
|
-
process.exit(1);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
main().catch(err => {
|
|
576
|
-
console.error('Error:', err.message);
|
|
577
|
-
process.exit(1);
|
|
578
|
-
});
|