@clawtrial/courtroom 1.0.6 ā 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 +64 -41
- package/package.json +20 -25
- package/scripts/postinstall.js +27 -99
- package/skills/courtroom/SKILL.md +49 -0
- package/src/api.js +12 -11
- package/src/crypto.js +5 -5
- package/src/debug.js +49 -121
- package/src/detector.js +40 -38
- package/src/hearing.js +246 -75
- package/src/plugin.js +435 -0
- package/src/punishment.js +13 -13
- package/src/storage.js +35 -119
- package/AGENT_CONFIG.md +0 -66
- package/OPENCLAW_FIX.md +0 -127
- package/OPENCLAW_INSTALL.md +0 -63
- package/SECURITY.md +0 -124
- package/SKILL.md +0 -91
- package/SUBAGENT_APPROACH.md +0 -124
- package/TECHNICAL_OVERVIEW.md +0 -278
- package/_meta.json +0 -14
- package/clawdbot.plugin.json +0 -32
- package/icon.txt +0 -1
- package/scripts/check-and-trigger.js +0 -139
- package/scripts/clawtrial.js +0 -968
- package/scripts/clawtrial.js.bak +0 -531
- package/scripts/cli.js +0 -184
- package/scripts/optimized-cron-check.js +0 -137
- package/scripts/setup-cron.js +0 -118
- package/scripts/trigger-evaluation.js +0 -86
- package/skill.yaml +0 -28
- package/src/autostart.js +0 -175
- package/src/config.js +0 -207
- package/src/consent.js +0 -217
- package/src/core.js +0 -208
- package/src/daemon.js +0 -152
- package/src/detector-v1.js +0 -572
- package/src/environment.js +0 -344
- package/src/evaluator.js +0 -277
- package/src/hook.js +0 -266
- package/src/index.js +0 -373
- package/src/monitor.js +0 -194
- package/src/skill.js +0 -372
- package/src/standalone.js +0 -248
package/src/standalone.js
DELETED
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Standalone ClawTrial Monitor
|
|
5
|
-
* Monitors conversations by reading ClawDBot's session files or logs
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const { getConfigDir } = require('./environment');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const { logger } = require('./debug');
|
|
12
|
-
const { StatusManager } = require('./daemon');
|
|
13
|
-
const { OffenseDetector } = require('./detector');
|
|
14
|
-
const { HearingPipeline } = require('./hearing');
|
|
15
|
-
const { PunishmentSystem } = require('./punishment');
|
|
16
|
-
const { CryptoManager } = require('./crypto');
|
|
17
|
-
const { APISubmission } = require('./api');
|
|
18
|
-
const { ConfigManager } = require('./config');
|
|
19
|
-
|
|
20
|
-
const CLAWDBOT_DIR = path.join(getConfigDir());
|
|
21
|
-
const CONVERSATION_FILE = path.join(CLAWDBOT_DIR, 'conversations.jsonl');
|
|
22
|
-
const PID_FILE = path.join(CLAWDBOT_DIR, 'courtroom_monitor.pid');
|
|
23
|
-
|
|
24
|
-
class StandaloneMonitor {
|
|
25
|
-
constructor() {
|
|
26
|
-
this.messageBuffer = [];
|
|
27
|
-
this.lastProcessedTime = 0;
|
|
28
|
-
this.statusManager = new StatusManager();
|
|
29
|
-
this.detector = null;
|
|
30
|
-
this.hearing = null;
|
|
31
|
-
this.punishment = null;
|
|
32
|
-
this.crypto = null;
|
|
33
|
-
this.api = null;
|
|
34
|
-
this.config = null;
|
|
35
|
-
this.caseCount = 0;
|
|
36
|
-
this.enabled = false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async initialize() {
|
|
40
|
-
logger.info('STANDALONE', 'Initializing standalone monitor');
|
|
41
|
-
|
|
42
|
-
// Load config
|
|
43
|
-
const configPath = path.join(CLAWDBOT_DIR, 'courtroom_config.json');
|
|
44
|
-
if (!fs.existsSync(configPath)) {
|
|
45
|
-
throw new Error('Config not found. Run: clawtrial setup');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
49
|
-
if (!config.consent?.granted || config.enabled === false) {
|
|
50
|
-
throw new Error('Courtroom not enabled');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Create mock agent
|
|
54
|
-
const mockAgent = this.createMockAgent();
|
|
55
|
-
this.config = new ConfigManager(mockAgent);
|
|
56
|
-
|
|
57
|
-
// Initialize subsystems
|
|
58
|
-
this.crypto = new CryptoManager(mockAgent);
|
|
59
|
-
await this.crypto.initialize();
|
|
60
|
-
|
|
61
|
-
this.detector = new OffenseDetector(mockAgent, this.config);
|
|
62
|
-
this.hearing = new HearingPipeline(mockAgent, this.config);
|
|
63
|
-
this.punishment = new PunishmentSystem(mockAgent, this.config);
|
|
64
|
-
this.api = new APISubmission(mockAgent, this.config, this.crypto);
|
|
65
|
-
|
|
66
|
-
await this.punishment.initialize();
|
|
67
|
-
await this.api.initialize();
|
|
68
|
-
|
|
69
|
-
this.enabled = true;
|
|
70
|
-
|
|
71
|
-
this.statusManager.update({
|
|
72
|
-
running: true,
|
|
73
|
-
initialized: true,
|
|
74
|
-
agentType: 'standalone',
|
|
75
|
-
publicKey: this.crypto.getPublicKey(),
|
|
76
|
-
pid: process.pid,
|
|
77
|
-
startedAt: new Date().toISOString()
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
logger.info('STANDALONE', 'Monitor initialized');
|
|
81
|
-
|
|
82
|
-
// Start monitoring
|
|
83
|
-
this.startMonitoring();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
createMockAgent() {
|
|
87
|
-
const self = this;
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
id: 'standalone-monitor',
|
|
91
|
-
llm: {
|
|
92
|
-
call: async ({ messages }) => {
|
|
93
|
-
// Simple mock - in real implementation, this would use actual LLM
|
|
94
|
-
return { content: 'Verdict: GUILTY' };
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
memory: {
|
|
98
|
-
get: async (key) => null,
|
|
99
|
-
set: async (key, value) => {},
|
|
100
|
-
delete: async (key) => {}
|
|
101
|
-
},
|
|
102
|
-
session: {
|
|
103
|
-
getRecentHistory: async (n) => {
|
|
104
|
-
return self.messageBuffer.slice(-n).map(m => ({
|
|
105
|
-
role: m.role,
|
|
106
|
-
content: m.content
|
|
107
|
-
}));
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
send: async (message) => {
|
|
111
|
-
console.log('[COURTROOM]', message);
|
|
112
|
-
},
|
|
113
|
-
autonomy: {
|
|
114
|
-
registerHook: () => {},
|
|
115
|
-
unregisterHook: () => {}
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
startMonitoring() {
|
|
121
|
-
logger.info('STANDALONE', 'Starting conversation monitoring');
|
|
122
|
-
|
|
123
|
-
// Check for new messages every 5 seconds
|
|
124
|
-
setInterval(() => {
|
|
125
|
-
this.checkForNewMessages();
|
|
126
|
-
}, 5000);
|
|
127
|
-
|
|
128
|
-
// Evaluate every 30 seconds
|
|
129
|
-
setInterval(() => {
|
|
130
|
-
this.evaluateIfReady();
|
|
131
|
-
}, 30000);
|
|
132
|
-
|
|
133
|
-
// Keep alive
|
|
134
|
-
setInterval(() => {
|
|
135
|
-
this.statusManager.update({ lastHeartbeat: new Date().toISOString() });
|
|
136
|
-
}, 30000);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
checkForNewMessages() {
|
|
140
|
-
// For now, we'll use a simple approach - monitor will be triggered by CLI
|
|
141
|
-
// In a real implementation, this would read from ClawDBot's log files
|
|
142
|
-
logger.debug('STANDALONE', 'Checking for messages', { bufferSize: this.messageBuffer.length });
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async evaluateIfReady() {
|
|
146
|
-
if (!this.enabled || this.messageBuffer.length < 3) return;
|
|
147
|
-
|
|
148
|
-
logger.debug('STANDALONE', 'Evaluating messages', { count: this.messageBuffer.length });
|
|
149
|
-
|
|
150
|
-
const sessionHistory = this.messageBuffer.slice(-10);
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const detection = await this.detector.evaluate(
|
|
154
|
-
sessionHistory,
|
|
155
|
-
this.createMockAgent().memory
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
if (detection.triggered) {
|
|
159
|
-
await this.initiateHearing(detection);
|
|
160
|
-
}
|
|
161
|
-
} catch (err) {
|
|
162
|
-
logger.error('STANDALONE', 'Evaluation failed', { error: err.message });
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async initiateHearing(detection) {
|
|
167
|
-
logger.info('STANDALONE', 'Initiating hearing', { offense: detection.offense });
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
const verdict = await this.hearing.conductHearing(detection);
|
|
171
|
-
|
|
172
|
-
if (verdict.guilty) {
|
|
173
|
-
this.caseCount++;
|
|
174
|
-
|
|
175
|
-
this.statusManager.update({
|
|
176
|
-
casesFiled: this.caseCount,
|
|
177
|
-
lastCase: {
|
|
178
|
-
timestamp: new Date().toISOString(),
|
|
179
|
-
offense: detection.offense,
|
|
180
|
-
verdict: verdict.verdict
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
await this.punishment.execute(verdict);
|
|
185
|
-
await this.api.submitCase(verdict);
|
|
186
|
-
|
|
187
|
-
logger.info('STANDALONE', 'Case filed', { caseId: verdict.caseId });
|
|
188
|
-
|
|
189
|
-
console.log(`\nšļø CASE FILED: ${detection.offense}`);
|
|
190
|
-
console.log(`š Case ID: ${verdict.caseId}`);
|
|
191
|
-
console.log(`āļø Verdict: ${verdict.verdict}`);
|
|
192
|
-
console.log(`š View: https://clawtrial.app/cases/${verdict.caseId}\n`);
|
|
193
|
-
}
|
|
194
|
-
} catch (err) {
|
|
195
|
-
logger.error('STANDALONE', 'Hearing failed', { error: err.message });
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
recordMessage(role, content) {
|
|
200
|
-
if (!this.enabled) return;
|
|
201
|
-
|
|
202
|
-
this.messageBuffer.push({
|
|
203
|
-
timestamp: Date.now(),
|
|
204
|
-
role,
|
|
205
|
-
content
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// Keep only last 100 messages
|
|
209
|
-
if (this.messageBuffer.length > 100) {
|
|
210
|
-
this.messageBuffer.shift();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
logger.debug('STANDALONE', 'Message recorded', { role, length: content.length });
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
async shutdown() {
|
|
217
|
-
this.enabled = false;
|
|
218
|
-
this.statusManager.update({ running: false });
|
|
219
|
-
logger.info('STANDALONE', 'Monitor shut down');
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// If run directly, start the monitor
|
|
224
|
-
if (require.main === module) {
|
|
225
|
-
const monitor = new StandaloneMonitor();
|
|
226
|
-
|
|
227
|
-
monitor.initialize().then(() => {
|
|
228
|
-
console.log('šļø ClawTrial standalone monitor started');
|
|
229
|
-
console.log('PID:', process.pid);
|
|
230
|
-
|
|
231
|
-
// Save PID
|
|
232
|
-
fs.writeFileSync(PID_FILE, process.pid.toString());
|
|
233
|
-
|
|
234
|
-
// Handle shutdown
|
|
235
|
-
process.on('SIGTERM', () => {
|
|
236
|
-
monitor.shutdown().then(() => process.exit(0));
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
process.on('SIGINT', () => {
|
|
240
|
-
monitor.shutdown().then(() => process.exit(0));
|
|
241
|
-
});
|
|
242
|
-
}).catch(err => {
|
|
243
|
-
console.error('Failed to start monitor:', err.message);
|
|
244
|
-
process.exit(1);
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
module.exports = { StandaloneMonitor };
|