@neuroverseos/governance 0.2.3 → 0.3.1

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.
Files changed (118) hide show
  1. package/package.json +4 -2
  2. package/policies/content-moderation-rules.txt +8 -0
  3. package/policies/marketing-rules.txt +8 -0
  4. package/policies/science-research-rules.txt +11 -0
  5. package/policies/social-media-rules.txt +7 -0
  6. package/policies/strict-rules.txt +8 -0
  7. package/policies/trading-rules.txt +8 -0
  8. package/simulate.html +1899 -0
  9. package/dist/adapters/autoresearch.cjs +0 -196
  10. package/dist/adapters/autoresearch.d.cts +0 -103
  11. package/dist/adapters/autoresearch.d.ts +0 -103
  12. package/dist/adapters/autoresearch.js +0 -7
  13. package/dist/adapters/deep-agents.cjs +0 -1472
  14. package/dist/adapters/deep-agents.d.cts +0 -181
  15. package/dist/adapters/deep-agents.d.ts +0 -181
  16. package/dist/adapters/deep-agents.js +0 -17
  17. package/dist/adapters/express.cjs +0 -1196
  18. package/dist/adapters/express.d.cts +0 -66
  19. package/dist/adapters/express.d.ts +0 -66
  20. package/dist/adapters/express.js +0 -12
  21. package/dist/adapters/index.cjs +0 -2038
  22. package/dist/adapters/index.d.cts +0 -8
  23. package/dist/adapters/index.d.ts +0 -8
  24. package/dist/adapters/index.js +0 -68
  25. package/dist/adapters/langchain.cjs +0 -1259
  26. package/dist/adapters/langchain.d.cts +0 -89
  27. package/dist/adapters/langchain.d.ts +0 -89
  28. package/dist/adapters/langchain.js +0 -17
  29. package/dist/adapters/openai.cjs +0 -1289
  30. package/dist/adapters/openai.d.cts +0 -99
  31. package/dist/adapters/openai.d.ts +0 -99
  32. package/dist/adapters/openai.js +0 -17
  33. package/dist/adapters/openclaw.cjs +0 -1281
  34. package/dist/adapters/openclaw.d.cts +0 -99
  35. package/dist/adapters/openclaw.d.ts +0 -99
  36. package/dist/adapters/openclaw.js +0 -17
  37. package/dist/bootstrap-GXVDZNF7.js +0 -114
  38. package/dist/build-X5MZY4IA.js +0 -339
  39. package/dist/chunk-4L6OPKMQ.js +0 -100
  40. package/dist/chunk-4NGDRRQH.js +0 -10
  41. package/dist/chunk-5U2MQO5P.js +0 -57
  42. package/dist/chunk-6BB55YJI.js +0 -113
  43. package/dist/chunk-6CZSKEY5.js +0 -164
  44. package/dist/chunk-7P3S7MAY.js +0 -1090
  45. package/dist/chunk-A5W4GNQO.js +0 -130
  46. package/dist/chunk-AF2VX4AL.js +0 -363
  47. package/dist/chunk-AKW5YVCE.js +0 -96
  48. package/dist/chunk-BMOXICAB.js +0 -340
  49. package/dist/chunk-BQZMOEML.js +0 -43
  50. package/dist/chunk-D2UCV5AK.js +0 -326
  51. package/dist/chunk-EVDJUSZ2.js +0 -91
  52. package/dist/chunk-FYS2CBUW.js +0 -304
  53. package/dist/chunk-I3RRAYK2.js +0 -11
  54. package/dist/chunk-IZSO75NZ.js +0 -792
  55. package/dist/chunk-JCKSW2PZ.js +0 -304
  56. package/dist/chunk-JZPQGIKR.js +0 -79
  57. package/dist/chunk-KTFTTLTP.js +0 -246
  58. package/dist/chunk-MH7BT4VH.js +0 -15
  59. package/dist/chunk-ORJ3NOE6.js +0 -622
  60. package/dist/chunk-OT6PXH54.js +0 -61
  61. package/dist/chunk-Q6O7ZLO2.js +0 -62
  62. package/dist/chunk-QLPTHTVB.js +0 -253
  63. package/dist/chunk-REXY4LUL.js +0 -226
  64. package/dist/chunk-T5EUJQE5.js +0 -172
  65. package/dist/chunk-TTBKTF3P.js +0 -608
  66. package/dist/chunk-XPDMYECO.js +0 -642
  67. package/dist/chunk-YZFATT7X.js +0 -9
  68. package/dist/chunk-ZIVQNSZU.js +0 -119
  69. package/dist/chunk-ZJTDUCC2.js +0 -194
  70. package/dist/cli/neuroverse.cjs +0 -12564
  71. package/dist/cli/neuroverse.d.cts +0 -1
  72. package/dist/cli/neuroverse.d.ts +0 -1
  73. package/dist/cli/neuroverse.js +0 -208
  74. package/dist/cli/plan.cjs +0 -1686
  75. package/dist/cli/plan.d.cts +0 -20
  76. package/dist/cli/plan.d.ts +0 -20
  77. package/dist/cli/plan.js +0 -353
  78. package/dist/cli/run.cjs +0 -1945
  79. package/dist/cli/run.d.cts +0 -20
  80. package/dist/cli/run.d.ts +0 -20
  81. package/dist/cli/run.js +0 -143
  82. package/dist/configure-ai-TK67ZWZL.js +0 -132
  83. package/dist/decision-flow-LETV5NWY.js +0 -61
  84. package/dist/derive-7365SUFU.js +0 -152
  85. package/dist/doctor-QYISMKEL.js +0 -173
  86. package/dist/equity-penalties-63FGB3I2.js +0 -244
  87. package/dist/explain-A2EWI2OL.js +0 -51
  88. package/dist/guard-3BWL3IGH.js +0 -92
  89. package/dist/guard-contract-C9_zKbzd.d.cts +0 -821
  90. package/dist/guard-contract-C9_zKbzd.d.ts +0 -821
  91. package/dist/guard-engine-QFMIBWJY.js +0 -10
  92. package/dist/impact-UB6DXKSX.js +0 -59
  93. package/dist/improve-XZA57GER.js +0 -66
  94. package/dist/index.cjs +0 -6821
  95. package/dist/index.d.cts +0 -1829
  96. package/dist/index.d.ts +0 -1829
  97. package/dist/index.js +0 -430
  98. package/dist/infer-world-7GVZWFX4.js +0 -543
  99. package/dist/init-PKPIYHYE.js +0 -144
  100. package/dist/init-world-VWMQZQC7.js +0 -223
  101. package/dist/mcp-server-XWQZXNW7.js +0 -13
  102. package/dist/model-adapter-BB7G4MFI.js +0 -11
  103. package/dist/playground-ADWZORNV.js +0 -550
  104. package/dist/redteam-JRQ7FD2F.js +0 -357
  105. package/dist/session-MMYX5YCF.js +0 -15
  106. package/dist/shared--Q8wPBVN.d.ts +0 -60
  107. package/dist/shared-HpAG90PX.d.cts +0 -60
  108. package/dist/shared-U2QFV7JH.js +0 -16
  109. package/dist/simulate-GMIFFXYV.js +0 -83
  110. package/dist/test-JBBZ65X4.js +0 -217
  111. package/dist/trace-3MYWIDEF.js +0 -166
  112. package/dist/validate-LLBWVPGV.js +0 -81
  113. package/dist/validate-engine-UIABSIHD.js +0 -7
  114. package/dist/world-BFJCIQSH.js +0 -378
  115. package/dist/world-loader-HMPTOEA2.js +0 -9
  116. package/dist/worlds/autoresearch.nv-world.md +0 -230
  117. package/dist/worlds/coding-agent.nv-world.md +0 -211
  118. package/dist/worlds/derivation-world.nv-world.md +0 -278
@@ -1,608 +0,0 @@
1
- import {
2
- describeActiveWorld,
3
- resolveWorldPath
4
- } from "./chunk-AKW5YVCE.js";
5
- import {
6
- evaluateGuard
7
- } from "./chunk-IZSO75NZ.js";
8
- import {
9
- advancePlan,
10
- evaluatePlan,
11
- getPlanProgress
12
- } from "./chunk-QLPTHTVB.js";
13
- import {
14
- loadWorld
15
- } from "./chunk-JZPQGIKR.js";
16
-
17
- // src/runtime/mcp-server.ts
18
- import { execSync } from "child_process";
19
- import { readFileSync, writeFileSync, readdirSync, statSync } from "fs";
20
- import { join, resolve } from "path";
21
- var GOVERNED_TOOLS = [
22
- {
23
- name: "governed_shell",
24
- description: "Execute a shell command. This command is evaluated against governance rules before execution.",
25
- inputSchema: {
26
- type: "object",
27
- properties: {
28
- command: { type: "string", description: "The shell command to execute" }
29
- },
30
- required: ["command"]
31
- }
32
- },
33
- {
34
- name: "governed_read_file",
35
- description: "Read a file. This action is evaluated against governance rules before execution.",
36
- inputSchema: {
37
- type: "object",
38
- properties: {
39
- path: { type: "string", description: "File path to read" }
40
- },
41
- required: ["path"]
42
- }
43
- },
44
- {
45
- name: "governed_write_file",
46
- description: "Write content to a file. This action is evaluated against governance rules before execution.",
47
- inputSchema: {
48
- type: "object",
49
- properties: {
50
- path: { type: "string", description: "File path to write" },
51
- content: { type: "string", description: "Content to write" }
52
- },
53
- required: ["path", "content"]
54
- }
55
- },
56
- {
57
- name: "governed_list_directory",
58
- description: "List files in a directory. This action is evaluated against governance rules.",
59
- inputSchema: {
60
- type: "object",
61
- properties: {
62
- path: { type: "string", description: "Directory path to list" }
63
- },
64
- required: ["path"]
65
- }
66
- },
67
- {
68
- name: "governed_http_request",
69
- description: "Make an HTTP request. This action is evaluated against governance rules before execution.",
70
- inputSchema: {
71
- type: "object",
72
- properties: {
73
- url: { type: "string", description: "URL to request" },
74
- method: { type: "string", description: "HTTP method (GET, POST, PUT, DELETE)", default: "GET" },
75
- body: { type: "string", description: "Request body (for POST/PUT)" },
76
- headers: { type: "object", description: "Request headers" }
77
- },
78
- required: ["url"]
79
- }
80
- },
81
- // Governance introspection tools — always available
82
- {
83
- name: "governance_check",
84
- description: "Check if an action would be allowed by governance rules without executing it.",
85
- inputSchema: {
86
- type: "object",
87
- properties: {
88
- intent: { type: "string", description: "What the action intends to do" },
89
- tool: { type: "string", description: "Tool name (shell, http, file, etc.)" },
90
- scope: { type: "string", description: "Scope (file path, URL, etc.)" }
91
- },
92
- required: ["intent"]
93
- }
94
- },
95
- {
96
- name: "governance_plan_status",
97
- description: "Show current plan progress and remaining steps.",
98
- inputSchema: {
99
- type: "object",
100
- properties: {}
101
- }
102
- },
103
- {
104
- name: "governance_plan_advance",
105
- description: "Mark a plan step as completed.",
106
- inputSchema: {
107
- type: "object",
108
- properties: {
109
- step_id: { type: "string", description: "ID of the step to mark as completed" }
110
- },
111
- required: ["step_id"]
112
- }
113
- }
114
- ];
115
- function executeShell(command, workingDir) {
116
- try {
117
- const result = execSync(command, {
118
- cwd: workingDir,
119
- encoding: "utf-8",
120
- timeout: 3e4,
121
- maxBuffer: 1024 * 1024
122
- });
123
- return result;
124
- } catch (err) {
125
- return `Error: ${err.message}
126
- ${err.stderr ?? ""}`;
127
- }
128
- }
129
- function executeReadFile(path, workingDir) {
130
- const fullPath = resolve(workingDir ?? ".", path);
131
- return readFileSync(fullPath, "utf-8");
132
- }
133
- function executeWriteFile(path, content, workingDir) {
134
- const fullPath = resolve(workingDir ?? ".", path);
135
- writeFileSync(fullPath, content);
136
- return `File written: ${fullPath}`;
137
- }
138
- function executeListDir(path, workingDir) {
139
- const fullPath = resolve(workingDir ?? ".", path);
140
- const entries = readdirSync(fullPath);
141
- return entries.map((e) => {
142
- try {
143
- const stat = statSync(join(fullPath, e));
144
- return `${stat.isDirectory() ? "d" : "-"} ${e}`;
145
- } catch {
146
- return `? ${e}`;
147
- }
148
- }).join("\n");
149
- }
150
- async function executeHttpRequest(url, method, body, headers) {
151
- const response = await fetch(url, {
152
- method: method || "GET",
153
- body: body || void 0,
154
- headers: { "Content-Type": "application/json", ...headers }
155
- });
156
- const text = await response.text();
157
- return `HTTP ${response.status}
158
- ${text}`;
159
- }
160
- var McpGovernanceServer = class {
161
- world;
162
- plan;
163
- config;
164
- engineOptions;
165
- initialized = false;
166
- // Stats
167
- actionsEvaluated = 0;
168
- actionsAllowed = 0;
169
- actionsBlocked = 0;
170
- constructor(config) {
171
- this.config = config;
172
- this.plan = config.plan;
173
- this.engineOptions = {
174
- trace: config.trace ?? false,
175
- level: config.level,
176
- plan: this.plan
177
- };
178
- }
179
- /**
180
- * Start the MCP server — reads JSON-RPC from stdin, writes to stdout.
181
- */
182
- async start() {
183
- if (this.config.worldPath) {
184
- this.world = await loadWorld(this.config.worldPath);
185
- } else if (this.config.world) {
186
- this.world = this.config.world;
187
- } else {
188
- throw new Error("No world provided");
189
- }
190
- if (this.config.planPath && !this.plan) {
191
- this.plan = JSON.parse(readFileSync(this.config.planPath, "utf-8"));
192
- this.engineOptions.plan = this.plan;
193
- }
194
- process.stderr.write(`[neuroverse-mcp] Server starting
195
- `);
196
- process.stderr.write(`[neuroverse-mcp] World: ${this.world.world.name}
197
- `);
198
- if (this.plan) {
199
- process.stderr.write(`[neuroverse-mcp] Plan: ${this.plan.plan_id}
200
- `);
201
- }
202
- let buffer = "";
203
- process.stdin.setEncoding("utf-8");
204
- process.stdin.on("data", (chunk) => {
205
- buffer += chunk;
206
- while (buffer.length > 0) {
207
- const headerEnd = buffer.indexOf("\r\n\r\n");
208
- if (headerEnd === -1) break;
209
- const header = buffer.slice(0, headerEnd);
210
- const contentLengthMatch = header.match(/Content-Length:\s*(\d+)/i);
211
- if (!contentLengthMatch) {
212
- const newlineIdx = buffer.indexOf("\n");
213
- if (newlineIdx === -1) break;
214
- const line = buffer.slice(0, newlineIdx).trim();
215
- buffer = buffer.slice(newlineIdx + 1);
216
- if (line) this.handleRawLine(line);
217
- continue;
218
- }
219
- const contentLength = parseInt(contentLengthMatch[1], 10);
220
- const bodyStart = headerEnd + 4;
221
- const bodyEnd = bodyStart + contentLength;
222
- if (buffer.length < bodyEnd) break;
223
- const body = buffer.slice(bodyStart, bodyEnd);
224
- buffer = buffer.slice(bodyEnd);
225
- this.handleRawLine(body);
226
- }
227
- });
228
- process.stdin.on("end", () => {
229
- process.stderr.write(
230
- `[neuroverse-mcp] Server stopped. Evaluated: ${this.actionsEvaluated}, Allowed: ${this.actionsAllowed}, Blocked: ${this.actionsBlocked}
231
- `
232
- );
233
- });
234
- await new Promise(() => {
235
- });
236
- }
237
- handleRawLine(line) {
238
- try {
239
- const msg = JSON.parse(line);
240
- if (msg.method) {
241
- if (msg.id !== void 0) {
242
- this.handleRequest(msg);
243
- } else {
244
- this.handleNotification(msg);
245
- }
246
- }
247
- } catch (err) {
248
- process.stderr.write(`[neuroverse-mcp] Parse error: ${err}
249
- `);
250
- }
251
- }
252
- send(msg) {
253
- const json = JSON.stringify(msg);
254
- const header = `Content-Length: ${Buffer.byteLength(json)}\r
255
- \r
256
- `;
257
- process.stdout.write(header + json);
258
- }
259
- sendResult(id, result) {
260
- this.send({ jsonrpc: "2.0", id, result });
261
- }
262
- sendError(id, code, message) {
263
- this.send({ jsonrpc: "2.0", id, error: { code, message } });
264
- }
265
- // ─── Request Handlers ───────────────────────────────────────────────────
266
- handleRequest(request) {
267
- switch (request.method) {
268
- case "initialize":
269
- this.handleInitialize(request);
270
- break;
271
- case "tools/list":
272
- this.handleToolsList(request);
273
- break;
274
- case "tools/call":
275
- this.handleToolsCall(request);
276
- break;
277
- case "ping":
278
- this.sendResult(request.id, {});
279
- break;
280
- default:
281
- this.sendError(request.id, -32601, `Method not found: ${request.method}`);
282
- }
283
- }
284
- handleNotification(notification) {
285
- switch (notification.method) {
286
- case "notifications/initialized":
287
- this.initialized = true;
288
- process.stderr.write(`[neuroverse-mcp] Client initialized
289
- `);
290
- break;
291
- case "notifications/cancelled":
292
- break;
293
- default:
294
- process.stderr.write(`[neuroverse-mcp] Unknown notification: ${notification.method}
295
- `);
296
- }
297
- }
298
- handleInitialize(request) {
299
- this.sendResult(request.id, {
300
- protocolVersion: "2024-11-05",
301
- capabilities: {
302
- tools: {}
303
- },
304
- serverInfo: {
305
- name: "neuroverse-governance",
306
- version: "0.2.0"
307
- }
308
- });
309
- }
310
- handleToolsList(request) {
311
- const tools = [];
312
- if (this.config.enableShell !== false) {
313
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governed_shell"));
314
- }
315
- if (this.config.enableFiles !== false) {
316
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governed_read_file"));
317
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governed_write_file"));
318
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governed_list_directory"));
319
- }
320
- if (this.config.enableHttp !== false) {
321
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governed_http_request"));
322
- }
323
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governance_check"));
324
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governance_plan_status"));
325
- if (this.plan) {
326
- tools.push(GOVERNED_TOOLS.find((t) => t.name === "governance_plan_advance"));
327
- }
328
- this.sendResult(request.id, { tools });
329
- }
330
- async handleToolsCall(request) {
331
- const params = request.params;
332
- const toolName = params.name;
333
- const args = params.arguments ?? {};
334
- try {
335
- const result = await this.executeTool(toolName, args);
336
- this.sendResult(request.id, result);
337
- } catch (err) {
338
- this.sendResult(request.id, {
339
- content: [{ type: "text", text: `Error: ${err.message}` }],
340
- isError: true
341
- });
342
- }
343
- }
344
- // ─── Tool Execution with Governance ─────────────────────────────────────
345
- async executeTool(name, args) {
346
- if (name === "governance_check") {
347
- return this.toolGovernanceCheck(args);
348
- }
349
- if (name === "governance_plan_status") {
350
- return this.toolPlanStatus();
351
- }
352
- if (name === "governance_plan_advance") {
353
- return this.toolPlanAdvance(args);
354
- }
355
- const event = this.buildEvent(name, args);
356
- this.engineOptions.plan = this.plan;
357
- const verdict = evaluateGuard(event, this.world, this.engineOptions);
358
- this.actionsEvaluated++;
359
- if (verdict.status === "BLOCK") {
360
- this.actionsBlocked++;
361
- let reason = `[GOVERNANCE BLOCKED] ${verdict.reason ?? "Action blocked by governance rules."}`;
362
- if (verdict.ruleId) reason += ` (Rule: ${verdict.ruleId})`;
363
- if (verdict.trace?.planCheck && !verdict.trace.planCheck.matched) {
364
- const pc = verdict.trace.planCheck;
365
- if (pc.closestStepLabel) {
366
- reason += `
367
- Closest plan step: "${pc.closestStepLabel}"`;
368
- }
369
- }
370
- process.stderr.write(`[neuroverse-mcp] BLOCKED: ${event.intent}
371
- `);
372
- return { content: [{ type: "text", text: reason }], isError: true };
373
- }
374
- if (verdict.status === "PAUSE") {
375
- this.actionsBlocked++;
376
- const reason = `[GOVERNANCE PAUSED] ${verdict.reason ?? "Action requires human approval."}`;
377
- process.stderr.write(`[neuroverse-mcp] PAUSED: ${event.intent}
378
- `);
379
- return { content: [{ type: "text", text: reason }], isError: true };
380
- }
381
- this.actionsAllowed++;
382
- process.stderr.write(`[neuroverse-mcp] ALLOWED: ${event.intent}
383
- `);
384
- const result = await this.executeActualTool(name, args);
385
- if (this.plan) {
386
- const planVerdict = evaluatePlan(event, this.plan);
387
- if (planVerdict.matchedStep) {
388
- const advResult = advancePlan(this.plan, planVerdict.matchedStep);
389
- if (advResult.success && advResult.plan) {
390
- this.plan = advResult.plan;
391
- this.engineOptions.plan = this.plan;
392
- }
393
- const progress = getPlanProgress(this.plan);
394
- process.stderr.write(
395
- `[neuroverse-mcp] Plan: ${progress.completed}/${progress.total} (${progress.percentage}%)
396
- `
397
- );
398
- if (progress.completed === progress.total) {
399
- process.stderr.write(`[neuroverse-mcp] Plan complete!
400
- `);
401
- }
402
- }
403
- }
404
- return result;
405
- }
406
- buildEvent(toolName, args) {
407
- switch (toolName) {
408
- case "governed_shell":
409
- return {
410
- intent: `execute shell command: ${args.command}`,
411
- tool: "shell",
412
- scope: String(args.command ?? ""),
413
- actionCategory: "shell",
414
- args,
415
- direction: "input"
416
- };
417
- case "governed_read_file":
418
- return {
419
- intent: `read file: ${args.path}`,
420
- tool: "fs",
421
- scope: String(args.path ?? ""),
422
- actionCategory: "read",
423
- args,
424
- direction: "input"
425
- };
426
- case "governed_write_file":
427
- return {
428
- intent: `write file: ${args.path}`,
429
- tool: "fs",
430
- scope: String(args.path ?? ""),
431
- actionCategory: "write",
432
- args,
433
- direction: "input"
434
- };
435
- case "governed_list_directory":
436
- return {
437
- intent: `list directory: ${args.path}`,
438
- tool: "fs",
439
- scope: String(args.path ?? ""),
440
- actionCategory: "read",
441
- args,
442
- direction: "input"
443
- };
444
- case "governed_http_request":
445
- return {
446
- intent: `http ${args.method ?? "GET"} ${args.url}`,
447
- tool: "http",
448
- scope: String(args.url ?? ""),
449
- actionCategory: "network",
450
- args,
451
- direction: "input"
452
- };
453
- default:
454
- return {
455
- intent: `${toolName}: ${JSON.stringify(args)}`,
456
- tool: toolName,
457
- args,
458
- direction: "input"
459
- };
460
- }
461
- }
462
- async executeActualTool(name, args) {
463
- const workingDir = this.config.workingDir;
464
- switch (name) {
465
- case "governed_shell": {
466
- const output = executeShell(String(args.command), workingDir);
467
- return { content: [{ type: "text", text: output }] };
468
- }
469
- case "governed_read_file": {
470
- const content = executeReadFile(String(args.path), workingDir);
471
- return { content: [{ type: "text", text: content }] };
472
- }
473
- case "governed_write_file": {
474
- const result = executeWriteFile(String(args.path), String(args.content), workingDir);
475
- return { content: [{ type: "text", text: result }] };
476
- }
477
- case "governed_list_directory": {
478
- const listing = executeListDir(String(args.path), workingDir);
479
- return { content: [{ type: "text", text: listing }] };
480
- }
481
- case "governed_http_request": {
482
- const result = await executeHttpRequest(
483
- String(args.url),
484
- String(args.method ?? "GET"),
485
- args.body,
486
- args.headers
487
- );
488
- return { content: [{ type: "text", text: result }] };
489
- }
490
- default:
491
- return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
492
- }
493
- }
494
- // ─── Governance Introspection Tools ─────────────────────────────────────
495
- toolGovernanceCheck(args) {
496
- const event = {
497
- intent: String(args.intent ?? ""),
498
- tool: args.tool,
499
- scope: args.scope,
500
- direction: "input"
501
- };
502
- this.engineOptions.plan = this.plan;
503
- const verdict = evaluateGuard(event, this.world, this.engineOptions);
504
- const lines = [
505
- `Verdict: ${verdict.status}`,
506
- verdict.reason ? `Reason: ${verdict.reason}` : null,
507
- verdict.ruleId ? `Rule: ${verdict.ruleId}` : null,
508
- verdict.warning ? `Warning: ${verdict.warning}` : null
509
- ].filter(Boolean).join("\n");
510
- return { content: [{ type: "text", text: lines }] };
511
- }
512
- toolPlanStatus() {
513
- if (!this.plan) {
514
- return { content: [{ type: "text", text: "No active plan." }] };
515
- }
516
- const progress = getPlanProgress(this.plan);
517
- const lines = [
518
- `Plan: ${this.plan.plan_id}`,
519
- `Objective: ${this.plan.objective}`,
520
- `Progress: ${progress.completed}/${progress.total} (${progress.percentage}%)`,
521
- "",
522
- "Steps:",
523
- ...this.plan.steps.map((s) => {
524
- const icon = s.status === "completed" ? "[x]" : s.status === "active" ? "[>]" : "[ ]";
525
- return ` ${icon} ${s.label} (${s.id})`;
526
- })
527
- ];
528
- if (this.plan.constraints.length > 0) {
529
- lines.push("", "Constraints:");
530
- for (const c of this.plan.constraints) {
531
- lines.push(` - ${c.description} [${c.type}]`);
532
- }
533
- }
534
- return { content: [{ type: "text", text: lines.join("\n") }] };
535
- }
536
- toolPlanAdvance(args) {
537
- if (!this.plan) {
538
- return { content: [{ type: "text", text: "No active plan." }], isError: true };
539
- }
540
- const stepId = String(args.step_id ?? "");
541
- const step = this.plan.steps.find((s) => s.id === stepId);
542
- if (!step) {
543
- const ids = this.plan.steps.map((s) => s.id).join(", ");
544
- return {
545
- content: [{ type: "text", text: `Step "${stepId}" not found. Available: ${ids}` }],
546
- isError: true
547
- };
548
- }
549
- if (step.status === "completed") {
550
- return { content: [{ type: "text", text: `Step "${stepId}" is already completed.` }] };
551
- }
552
- const advResult = advancePlan(this.plan, stepId);
553
- if (!advResult.success) {
554
- return { content: [{ type: "text", text: `Cannot advance: ${advResult.reason}` }] };
555
- }
556
- this.plan = advResult.plan;
557
- this.engineOptions.plan = this.plan;
558
- const progress = getPlanProgress(this.plan);
559
- let text = `Step completed: ${step.label}
560
- Progress: ${progress.completed}/${progress.total} (${progress.percentage}%)`;
561
- if (progress.completed === progress.total) {
562
- text += "\n\nPlan complete!";
563
- }
564
- if (this.config.planPath) {
565
- writeFileSync(this.config.planPath, JSON.stringify(this.plan, null, 2) + "\n");
566
- }
567
- return { content: [{ type: "text", text }] };
568
- }
569
- };
570
- async function startMcpServer(args) {
571
- function parseArg(flag) {
572
- const idx = args.indexOf(flag);
573
- return idx >= 0 && idx + 1 < args.length ? args[idx + 1] : void 0;
574
- }
575
- const worldPath = resolveWorldPath(parseArg("--world"));
576
- const planPath = parseArg("--plan");
577
- const level = parseArg("--level");
578
- const trace = args.includes("--trace");
579
- const workingDir = parseArg("--cwd");
580
- if (!worldPath) {
581
- process.stderr.write(
582
- "Error: No world found.\nUse --world <path>, set NEUROVERSE_WORLD, or run `neuroverse world use <name>`\n"
583
- );
584
- process.exit(1);
585
- return;
586
- }
587
- const worldInfo = describeActiveWorld(parseArg("--world"));
588
- if (worldInfo) {
589
- process.stderr.write(`Using world: ${worldInfo.name}
590
- `);
591
- }
592
- const server = new McpGovernanceServer({
593
- worldPath,
594
- planPath,
595
- level,
596
- trace,
597
- workingDir,
598
- enableShell: !args.includes("--no-shell"),
599
- enableFiles: !args.includes("--no-files"),
600
- enableHttp: !args.includes("--no-http")
601
- });
602
- await server.start();
603
- }
604
-
605
- export {
606
- McpGovernanceServer,
607
- startMcpServer
608
- };