@neuroverseos/governance 0.3.0 → 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 (105) hide show
  1. package/README.md +20 -0
  2. package/package.json +16 -3
  3. package/policies/content-moderation-rules.txt +8 -0
  4. package/policies/marketing-rules.txt +8 -0
  5. package/policies/science-research-rules.txt +11 -0
  6. package/policies/social-media-rules.txt +7 -0
  7. package/policies/strict-rules.txt +8 -0
  8. package/policies/trading-rules.txt +8 -0
  9. package/simulate.html +1899 -0
  10. package/dist/adapters/autoresearch.cjs +0 -196
  11. package/dist/adapters/autoresearch.d.cts +0 -103
  12. package/dist/adapters/autoresearch.d.ts +0 -103
  13. package/dist/adapters/autoresearch.js +0 -7
  14. package/dist/adapters/express.cjs +0 -1114
  15. package/dist/adapters/express.d.cts +0 -66
  16. package/dist/adapters/express.d.ts +0 -66
  17. package/dist/adapters/express.js +0 -12
  18. package/dist/adapters/index.cjs +0 -1669
  19. package/dist/adapters/index.d.cts +0 -6
  20. package/dist/adapters/index.d.ts +0 -6
  21. package/dist/adapters/index.js +0 -46
  22. package/dist/adapters/langchain.cjs +0 -1155
  23. package/dist/adapters/langchain.d.cts +0 -89
  24. package/dist/adapters/langchain.d.ts +0 -89
  25. package/dist/adapters/langchain.js +0 -16
  26. package/dist/adapters/openai.cjs +0 -1185
  27. package/dist/adapters/openai.d.cts +0 -99
  28. package/dist/adapters/openai.d.ts +0 -99
  29. package/dist/adapters/openai.js +0 -16
  30. package/dist/adapters/openclaw.cjs +0 -1177
  31. package/dist/adapters/openclaw.d.cts +0 -99
  32. package/dist/adapters/openclaw.d.ts +0 -99
  33. package/dist/adapters/openclaw.js +0 -16
  34. package/dist/bootstrap-GXVDZNF7.js +0 -114
  35. package/dist/build-P42YFKQV.js +0 -339
  36. package/dist/chunk-2NICNKOM.js +0 -100
  37. package/dist/chunk-2PQU3VAN.js +0 -131
  38. package/dist/chunk-4A7LISES.js +0 -324
  39. package/dist/chunk-4JRYGIO7.js +0 -727
  40. package/dist/chunk-4NGDRRQH.js +0 -10
  41. package/dist/chunk-4QXB6PEO.js +0 -232
  42. package/dist/chunk-6CZSKEY5.js +0 -164
  43. package/dist/chunk-7P3S7MAY.js +0 -1090
  44. package/dist/chunk-A5W4GNQO.js +0 -130
  45. package/dist/chunk-AKW5YVCE.js +0 -96
  46. package/dist/chunk-BUWWN2NX.js +0 -192
  47. package/dist/chunk-COT5XS4V.js +0 -109
  48. package/dist/chunk-ER62HNGF.js +0 -139
  49. package/dist/chunk-FYS2CBUW.js +0 -304
  50. package/dist/chunk-GR6DGCZ2.js +0 -340
  51. package/dist/chunk-I3RRAYK2.js +0 -11
  52. package/dist/chunk-JZPQGIKR.js +0 -79
  53. package/dist/chunk-MWDQ4MJB.js +0 -11
  54. package/dist/chunk-NF5POFCI.js +0 -622
  55. package/dist/chunk-OGL7QXZS.js +0 -608
  56. package/dist/chunk-OT6PXH54.js +0 -61
  57. package/dist/chunk-PDOZHZWL.js +0 -225
  58. package/dist/chunk-Q6O7ZLO2.js +0 -62
  59. package/dist/chunk-QPASI2BR.js +0 -187
  60. package/dist/chunk-T5EUJQE5.js +0 -172
  61. package/dist/chunk-XPDMYECO.js +0 -642
  62. package/dist/chunk-YZFATT7X.js +0 -9
  63. package/dist/cli/neuroverse.cjs +0 -11448
  64. package/dist/cli/neuroverse.d.cts +0 -1
  65. package/dist/cli/neuroverse.d.ts +0 -1
  66. package/dist/cli/neuroverse.js +0 -196
  67. package/dist/cli/plan.cjs +0 -1599
  68. package/dist/cli/plan.d.cts +0 -20
  69. package/dist/cli/plan.d.ts +0 -20
  70. package/dist/cli/plan.js +0 -361
  71. package/dist/cli/run.cjs +0 -1746
  72. package/dist/cli/run.d.cts +0 -20
  73. package/dist/cli/run.d.ts +0 -20
  74. package/dist/cli/run.js +0 -143
  75. package/dist/configure-ai-TK67ZWZL.js +0 -132
  76. package/dist/derive-TLIV4OOU.js +0 -152
  77. package/dist/doctor-XPDLEYXN.js +0 -171
  78. package/dist/explain-IDCRWMPX.js +0 -70
  79. package/dist/guard-RV65TT4L.js +0 -96
  80. package/dist/guard-contract-WZx__PmU.d.cts +0 -709
  81. package/dist/guard-contract-WZx__PmU.d.ts +0 -709
  82. package/dist/guard-engine-JLTUARGU.js +0 -10
  83. package/dist/impact-XPECYRLH.js +0 -59
  84. package/dist/improve-GPUBKTEA.js +0 -85
  85. package/dist/index.cjs +0 -6273
  86. package/dist/index.d.cts +0 -1616
  87. package/dist/index.d.ts +0 -1616
  88. package/dist/index.js +0 -379
  89. package/dist/infer-world-7GVZWFX4.js +0 -543
  90. package/dist/init-PKPIYHYE.js +0 -144
  91. package/dist/init-world-VWMQZQC7.js +0 -223
  92. package/dist/mcp-server-FPVSU32Z.js +0 -13
  93. package/dist/model-adapter-BB7G4MFI.js +0 -11
  94. package/dist/playground-E664U4T6.js +0 -550
  95. package/dist/redteam-Z7WREJ44.js +0 -357
  96. package/dist/session-EKTRSR7C.js +0 -14
  97. package/dist/simulate-VDOYQFRO.js +0 -108
  98. package/dist/test-OGXJK4QU.js +0 -217
  99. package/dist/trace-JVF67VR3.js +0 -166
  100. package/dist/validate-LLBWVPGV.js +0 -81
  101. package/dist/validate-engine-UIABSIHD.js +0 -7
  102. package/dist/world-LAXO6DOX.js +0 -378
  103. package/dist/world-loader-HMPTOEA2.js +0 -9
  104. package/dist/worlds/autoresearch.nv-world.md +0 -230
  105. 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-4JRYGIO7.js";
8
- import {
9
- advancePlan,
10
- evaluatePlan,
11
- getPlanProgress
12
- } from "./chunk-4QXB6PEO.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
- };
@@ -1,61 +0,0 @@
1
- // src/providers/config-manager.ts
2
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
3
- import { join } from "path";
4
- import { homedir } from "os";
5
- function getConfigDir() {
6
- const xdg = process.env.XDG_CONFIG_HOME;
7
- if (xdg) return join(xdg, "neuroverse");
8
- return join(homedir(), ".neuroverse");
9
- }
10
- function getConfigPath() {
11
- return join(getConfigDir(), "config.json");
12
- }
13
- async function loadConfig() {
14
- try {
15
- const raw = await readFile(getConfigPath(), "utf-8");
16
- const parsed = JSON.parse(raw);
17
- if (!parsed.provider || !parsed.model || !parsed.apiKey) {
18
- return null;
19
- }
20
- return {
21
- provider: parsed.provider,
22
- model: parsed.model,
23
- apiKey: parsed.apiKey,
24
- endpoint: parsed.endpoint ?? null
25
- };
26
- } catch {
27
- return null;
28
- }
29
- }
30
- async function saveConfig(config) {
31
- const dir = getConfigDir();
32
- await mkdir(dir, { recursive: true });
33
- const configPath = getConfigPath();
34
- const content = JSON.stringify(
35
- {
36
- provider: config.provider,
37
- model: config.model,
38
- apiKey: config.apiKey,
39
- endpoint: config.endpoint
40
- },
41
- null,
42
- 2
43
- );
44
- await writeFile(configPath, content, { mode: 384 });
45
- await chmod(configPath, 384);
46
- }
47
- function redactConfig(config) {
48
- return {
49
- provider: config.provider,
50
- model: config.model,
51
- apiKey: config.apiKey ? `${config.apiKey.slice(0, 4)}...${config.apiKey.slice(-4)}` : "(not set)",
52
- endpoint: config.endpoint
53
- };
54
- }
55
-
56
- export {
57
- getConfigPath,
58
- loadConfig,
59
- saveConfig,
60
- redactConfig
61
- };