@neuroverseos/governance 0.3.0 → 0.3.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.
Files changed (126) hide show
  1. package/.well-known/ai-plugin.json +34 -9
  2. package/AGENTS.md +72 -24
  3. package/README.md +352 -237
  4. package/dist/adapters/autoresearch.cjs +1152 -3
  5. package/dist/adapters/autoresearch.d.cts +11 -3
  6. package/dist/adapters/autoresearch.d.ts +11 -3
  7. package/dist/adapters/autoresearch.js +9 -4
  8. package/dist/adapters/deep-agents.cjs +1528 -0
  9. package/dist/adapters/deep-agents.d.cts +181 -0
  10. package/dist/adapters/deep-agents.d.ts +181 -0
  11. package/dist/adapters/deep-agents.js +17 -0
  12. package/dist/adapters/express.cjs +171 -32
  13. package/dist/adapters/express.d.cts +1 -1
  14. package/dist/adapters/express.d.ts +1 -1
  15. package/dist/adapters/express.js +5 -5
  16. package/dist/adapters/index.cjs +564 -121
  17. package/dist/adapters/index.d.cts +3 -1
  18. package/dist/adapters/index.d.ts +3 -1
  19. package/dist/adapters/index.js +38 -16
  20. package/dist/adapters/langchain.cjs +217 -57
  21. package/dist/adapters/langchain.d.cts +5 -5
  22. package/dist/adapters/langchain.d.ts +5 -5
  23. package/dist/adapters/langchain.js +6 -5
  24. package/dist/adapters/openai.cjs +219 -59
  25. package/dist/adapters/openai.d.cts +5 -5
  26. package/dist/adapters/openai.d.ts +5 -5
  27. package/dist/adapters/openai.js +6 -5
  28. package/dist/adapters/openclaw.cjs +217 -57
  29. package/dist/adapters/openclaw.d.cts +6 -6
  30. package/dist/adapters/openclaw.d.ts +6 -6
  31. package/dist/adapters/openclaw.js +6 -5
  32. package/dist/add-ROOZLU62.js +314 -0
  33. package/dist/behavioral-MJO34S6Q.js +118 -0
  34. package/dist/{bootstrap-GXVDZNF7.js → bootstrap-CQRZVOXK.js} +6 -4
  35. package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
  36. package/dist/bootstrap-parser-EEF36XDU.js +7 -0
  37. package/dist/browser.global.js +941 -0
  38. package/dist/{build-P42YFKQV.js → build-QKOBBC23.js} +7 -5
  39. package/dist/{chunk-COT5XS4V.js → chunk-3WQLXYTP.js} +17 -35
  40. package/dist/{chunk-ER62HNGF.js → chunk-4FLICVVA.js} +17 -37
  41. package/dist/chunk-5TPFNWRU.js +215 -0
  42. package/dist/chunk-5U2MQO5P.js +57 -0
  43. package/dist/{chunk-NF5POFCI.js → chunk-6S5CFQXY.js} +6 -4
  44. package/dist/{chunk-QPASI2BR.js → chunk-A7GKPPU7.js} +49 -10
  45. package/dist/{chunk-OGL7QXZS.js → chunk-B6OXJLJ5.js} +17 -3
  46. package/dist/{chunk-2PQU3VAN.js → chunk-BNKJPUPQ.js} +17 -35
  47. package/dist/chunk-BQZMOEML.js +43 -0
  48. package/dist/chunk-CNSO6XW5.js +207 -0
  49. package/dist/{chunk-JZPQGIKR.js → chunk-CTZHONLA.js} +65 -9
  50. package/dist/chunk-D2UCV5AK.js +326 -0
  51. package/dist/{chunk-XPDMYECO.js → chunk-EMQDLDAF.js} +1 -185
  52. package/dist/{chunk-GR6DGCZ2.js → chunk-F66BVUYB.js} +3 -3
  53. package/dist/{chunk-2NICNKOM.js → chunk-G7DJ6VOD.js} +5 -4
  54. package/dist/{chunk-4A7LISES.js → chunk-IS4WUH6Y.js} +45 -6
  55. package/dist/{chunk-MWDQ4MJB.js → chunk-MH7BT4VH.js} +5 -1
  56. package/dist/chunk-O5ABKEA7.js +304 -0
  57. package/dist/chunk-PVTQQS3Y.js +186 -0
  58. package/dist/{chunk-4QXB6PEO.js → chunk-QLPTHTVB.js} +37 -16
  59. package/dist/chunk-QWGCMQQD.js +16 -0
  60. package/dist/{chunk-T5EUJQE5.js → chunk-QXBFT7NI.js} +31 -2
  61. package/dist/{chunk-PDOZHZWL.js → chunk-TG6SEF24.js} +25 -4
  62. package/dist/chunk-U6U7EJZL.js +177 -0
  63. package/dist/{chunk-4JRYGIO7.js → chunk-W7LLXRGY.js} +110 -7
  64. package/dist/{chunk-BUWWN2NX.js → chunk-ZJTDUCC2.js} +9 -7
  65. package/dist/{chunk-FYS2CBUW.js → chunk-ZWI3NIXK.js} +10 -0
  66. package/dist/cli/neuroverse.cjs +5091 -2348
  67. package/dist/cli/neuroverse.js +52 -21
  68. package/dist/cli/plan.cjs +881 -41
  69. package/dist/cli/plan.js +7 -15
  70. package/dist/cli/run.cjs +289 -34
  71. package/dist/cli/run.js +4 -4
  72. package/dist/{configure-ai-TK67ZWZL.js → configure-ai-6TZ3MCSI.js} +1 -1
  73. package/dist/decision-flow-M63D47LO.js +61 -0
  74. package/dist/demo-G43RLCPK.js +469 -0
  75. package/dist/{derive-TLIV4OOU.js → derive-FJZVIPUZ.js} +5 -4
  76. package/dist/{doctor-XPDLEYXN.js → doctor-6BC6X2VO.js} +6 -4
  77. package/dist/equity-penalties-SG5IZQ7I.js +244 -0
  78. package/dist/{explain-IDCRWMPX.js → explain-RHBU2GBR.js} +6 -25
  79. package/dist/{guard-RV65TT4L.js → guard-AJCCGZMF.js} +8 -12
  80. package/dist/{guard-contract-WZx__PmU.d.cts → guard-contract-DqFcTScd.d.cts} +117 -5
  81. package/dist/{guard-contract-WZx__PmU.d.ts → guard-contract-DqFcTScd.d.ts} +117 -5
  82. package/dist/{guard-engine-JLTUARGU.js → guard-engine-PNR6MHCM.js} +3 -3
  83. package/dist/{impact-XPECYRLH.js → impact-3XVDSCBU.js} +5 -5
  84. package/dist/{improve-GPUBKTEA.js → improve-TQP4ECSY.js} +7 -26
  85. package/dist/index.cjs +5597 -4279
  86. package/dist/index.d.cts +597 -18
  87. package/dist/index.d.ts +597 -18
  88. package/dist/index.js +134 -41
  89. package/dist/{infer-world-7GVZWFX4.js → infer-world-IFXCACJ5.js} +1 -1
  90. package/dist/{init-PKPIYHYE.js → init-FYPV4SST.js} +1 -1
  91. package/dist/{init-world-VWMQZQC7.js → init-world-TI7ARHBT.js} +1 -1
  92. package/dist/mcp-server-5Y3ZM7TV.js +13 -0
  93. package/dist/{model-adapter-BB7G4MFI.js → model-adapter-VXEKB4LS.js} +1 -1
  94. package/dist/{playground-E664U4T6.js → playground-VZBNPPBO.js} +29 -19
  95. package/dist/{redteam-Z7WREJ44.js → redteam-MZPZD3EF.js} +4 -4
  96. package/dist/session-JYOARW54.js +15 -0
  97. package/dist/shared-7RLUHNMU.js +16 -0
  98. package/dist/shared-B8dvUUD8.d.cts +60 -0
  99. package/dist/shared-Dr5Wiay8.d.ts +60 -0
  100. package/dist/{simulate-VDOYQFRO.js → simulate-LJXYBC6M.js} +8 -33
  101. package/dist/{test-OGXJK4QU.js → test-BOOR4A5F.js} +4 -4
  102. package/dist/{trace-JVF67VR3.js → trace-PKV4KX56.js} +4 -4
  103. package/dist/{validate-LLBWVPGV.js → validate-RALX7CZS.js} +2 -2
  104. package/dist/{validate-engine-UIABSIHD.js → validate-engine-7ZXFVGF2.js} +1 -1
  105. package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
  106. package/dist/viz/index.html +23 -0
  107. package/dist/{world-LAXO6DOX.js → world-BIP4GZBZ.js} +9 -11
  108. package/dist/world-loader-Y6HMQH2D.js +13 -0
  109. package/dist/worlds/coding-agent.nv-world.md +211 -0
  110. package/dist/worlds/research-agent.nv-world.md +169 -0
  111. package/dist/worlds/social-media.nv-world.md +198 -0
  112. package/dist/worlds/trading-agent.nv-world.md +218 -0
  113. package/examples/social-media-sim/bridge.py +209 -0
  114. package/examples/social-media-sim/simulation.py +927 -0
  115. package/package.json +30 -4
  116. package/policies/content-moderation-rules.txt +8 -0
  117. package/policies/marketing-rules.txt +8 -0
  118. package/policies/science-research-rules.txt +11 -0
  119. package/policies/social-media-rules.txt +7 -0
  120. package/policies/strict-rules.txt +8 -0
  121. package/policies/trading-rules.txt +8 -0
  122. package/simulate.html +1567 -0
  123. package/dist/chunk-YZFATT7X.js +0 -9
  124. package/dist/mcp-server-FPVSU32Z.js +0 -13
  125. package/dist/session-EKTRSR7C.js +0 -14
  126. package/dist/world-loader-HMPTOEA2.js +0 -9
@@ -1,23 +1,21 @@
1
1
  import {
2
- evaluateGuard
3
- } from "./chunk-4JRYGIO7.js";
2
+ GovernanceBlockedError,
3
+ buildEngineOptions,
4
+ extractScope,
5
+ trackPlanProgress
6
+ } from "./chunk-5U2MQO5P.js";
4
7
  import {
5
- advancePlan,
6
- evaluatePlan,
7
- getPlanProgress
8
- } from "./chunk-4QXB6PEO.js";
8
+ evaluateGuard
9
+ } from "./chunk-W7LLXRGY.js";
9
10
  import {
10
11
  loadWorld
11
- } from "./chunk-JZPQGIKR.js";
12
+ } from "./chunk-CTZHONLA.js";
12
13
 
13
14
  // src/adapters/openclaw.ts
14
- var GovernanceBlockedError = class extends Error {
15
- verdict;
15
+ var GovernanceBlockedError2 = class extends GovernanceBlockedError {
16
16
  action;
17
17
  constructor(verdict, action) {
18
- super(`[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
19
- this.name = "GovernanceBlockedError";
20
- this.verdict = verdict;
18
+ super(verdict);
21
19
  this.action = action;
22
20
  }
23
21
  };
@@ -27,7 +25,7 @@ function defaultMapAction(action, direction) {
27
25
  tool: action.tool ?? action.type,
28
26
  args: action.input,
29
27
  direction,
30
- scope: typeof action.input?.path === "string" ? action.input.path : typeof action.input?.url === "string" ? action.input.url : void 0
28
+ scope: action.input ? extractScope(action.input) : void 0
31
29
  };
32
30
  }
33
31
  var NeuroVersePlugin = class {
@@ -41,11 +39,7 @@ var NeuroVersePlugin = class {
41
39
  this.world = world;
42
40
  this.options = options;
43
41
  this.activePlan = options.plan;
44
- this.engineOptions = {
45
- trace: options.trace ?? false,
46
- level: options.level,
47
- plan: this.activePlan
48
- };
42
+ this.engineOptions = buildEngineOptions(options, this.activePlan);
49
43
  this.mapAction = options.mapAction ?? defaultMapAction;
50
44
  }
51
45
  /**
@@ -65,22 +59,10 @@ var NeuroVersePlugin = class {
65
59
  };
66
60
  this.options.onEvaluate?.(result);
67
61
  if (verdict.status === "BLOCK") {
68
- throw new GovernanceBlockedError(verdict, action);
62
+ throw new GovernanceBlockedError2(verdict, action);
69
63
  }
70
- if (verdict.status === "ALLOW" && this.activePlan) {
71
- const planVerdict = evaluatePlan(event, this.activePlan);
72
- if (planVerdict.matchedStep) {
73
- const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
74
- if (advResult.success && advResult.plan) {
75
- this.activePlan = advResult.plan;
76
- this.engineOptions.plan = this.activePlan;
77
- }
78
- const progress = getPlanProgress(this.activePlan);
79
- this.options.onPlanProgress?.(progress);
80
- if (progress.completed === progress.total) {
81
- this.options.onPlanComplete?.();
82
- }
83
- }
64
+ if (verdict.status === "ALLOW") {
65
+ trackPlanProgress(event, this, this.options);
84
66
  }
85
67
  return result;
86
68
  }
@@ -101,7 +83,7 @@ var NeuroVersePlugin = class {
101
83
  };
102
84
  this.options.onEvaluate?.(result);
103
85
  if (verdict.status === "BLOCK") {
104
- throw new GovernanceBlockedError(verdict, action);
86
+ throw new GovernanceBlockedError2(verdict, action);
105
87
  }
106
88
  return result;
107
89
  }
@@ -124,7 +106,7 @@ function createNeuroVersePluginFromWorld(world, options) {
124
106
  }
125
107
 
126
108
  export {
127
- GovernanceBlockedError,
109
+ GovernanceBlockedError2 as GovernanceBlockedError,
128
110
  NeuroVersePlugin,
129
111
  createNeuroVersePlugin,
130
112
  createNeuroVersePluginFromWorld
@@ -0,0 +1,43 @@
1
+ // src/cli/cli-utils.ts
2
+ async function resolveWorldPath(input) {
3
+ const { stat } = await import("fs/promises");
4
+ try {
5
+ const info = await stat(input);
6
+ if (info.isDirectory()) return input;
7
+ } catch {
8
+ }
9
+ const neuroversePath = `.neuroverse/worlds/${input}`;
10
+ try {
11
+ const info = await stat(neuroversePath);
12
+ if (info.isDirectory()) return neuroversePath;
13
+ } catch {
14
+ }
15
+ throw new Error(
16
+ `World not found: "${input}"
17
+ Tried:
18
+ ${input}
19
+ ${neuroversePath}
20
+
21
+ Build a world first: neuroverse build <input.md>`
22
+ );
23
+ }
24
+ async function readStdin() {
25
+ const chunks = [];
26
+ for await (const chunk of process.stdin) {
27
+ chunks.push(chunk);
28
+ }
29
+ return Buffer.concat(chunks).toString("utf-8");
30
+ }
31
+ function parseCliValue(raw) {
32
+ if (raw === "true") return true;
33
+ if (raw === "false") return false;
34
+ const num = Number(raw);
35
+ if (!isNaN(num) && raw.trim() !== "") return num;
36
+ return raw;
37
+ }
38
+
39
+ export {
40
+ resolveWorldPath,
41
+ readStdin,
42
+ parseCliValue
43
+ };
@@ -0,0 +1,207 @@
1
+ // src/engine/behavioral-engine.ts
2
+ var ACTION_CATEGORY_MAP = {
3
+ // Amplifying
4
+ share: "amplifying",
5
+ post: "amplifying",
6
+ create_post: "amplifying",
7
+ retweet: "amplifying",
8
+ quote_tweet: "amplifying",
9
+ broadcast: "amplifying",
10
+ publish: "amplifying",
11
+ // Passive
12
+ scroll: "passive",
13
+ idle: "passive",
14
+ observe: "passive",
15
+ like: "passive",
16
+ // Engaging
17
+ reply: "engaging",
18
+ comment: "engaging",
19
+ discuss: "engaging",
20
+ // Corrective
21
+ report: "corrective",
22
+ fact_check: "corrective",
23
+ flag: "corrective",
24
+ debunk: "corrective",
25
+ // Transactional
26
+ buy: "transactional",
27
+ sell: "transactional",
28
+ trade: "transactional",
29
+ short: "transactional",
30
+ // Creative
31
+ generate: "creative",
32
+ compose: "creative",
33
+ draft: "creative",
34
+ write: "creative",
35
+ // Analytical
36
+ analyze: "analytical",
37
+ research: "analytical",
38
+ investigate: "analytical",
39
+ review: "analytical"
40
+ };
41
+ var SHIFT_LABELS = {
42
+ "amplifying\u2192passive": "amplification_suppressed",
43
+ "amplifying\u2192corrective": "redirected_to_reporting",
44
+ "amplifying\u2192engaging": "shifted_to_engagement",
45
+ "amplifying\u2192analytical": "redirected_to_analysis",
46
+ "transactional\u2192passive": "trading_halted",
47
+ "transactional\u2192analytical": "redirected_to_analysis",
48
+ "creative\u2192passive": "creation_blocked",
49
+ "creative\u2192analytical": "redirected_to_research",
50
+ "engaging\u2192passive": "engagement_dampened",
51
+ "passive\u2192passive": "unchanged"
52
+ };
53
+ function categorizeAction(action) {
54
+ return ACTION_CATEGORY_MAP[action] ?? "unknown";
55
+ }
56
+ function classifyAdaptation(intendedAction, executedAction) {
57
+ if (intendedAction === executedAction) return "unchanged";
58
+ const intendedCat = categorizeAction(intendedAction);
59
+ const executedCat = categorizeAction(executedAction);
60
+ if (intendedCat === executedCat) return "unchanged";
61
+ const key = `${intendedCat}\u2192${executedCat}`;
62
+ return SHIFT_LABELS[key] ?? `${intendedAction}_to_${executedAction}`;
63
+ }
64
+ function adaptationFromVerdict(agentId, intendedAction, executedAction, verdict) {
65
+ return {
66
+ agentId,
67
+ intendedAction,
68
+ executedAction,
69
+ shiftType: classifyAdaptation(intendedAction, executedAction),
70
+ verdict: verdict.status,
71
+ ruleId: verdict.ruleId,
72
+ reason: verdict.reason
73
+ };
74
+ }
75
+ function detectBehavioralPatterns(adaptations, totalAgents) {
76
+ const patterns = [];
77
+ if (adaptations.length === 0) return patterns;
78
+ const n = Math.max(totalAgents, 1);
79
+ const shiftCounts = {};
80
+ for (const a of adaptations) {
81
+ shiftCounts[a.shiftType] = (shiftCounts[a.shiftType] ?? 0) + 1;
82
+ }
83
+ const verdictCounts = {};
84
+ for (const a of adaptations) {
85
+ verdictCounts[a.verdict] = (verdictCounts[a.verdict] ?? 0) + 1;
86
+ }
87
+ const suppressed = shiftCounts["amplification_suppressed"] ?? 0;
88
+ const dampened = shiftCounts["engagement_dampened"] ?? 0;
89
+ const silenced = suppressed + dampened;
90
+ if (silenced >= 3) {
91
+ patterns.push({
92
+ type: "coordinated_silence",
93
+ description: `${silenced} agents blocked from amplifying \u2014 network went quiet`,
94
+ strength: round(silenced / n),
95
+ agentsAffected: silenced
96
+ });
97
+ }
98
+ if (suppressed >= 2) {
99
+ patterns.push({
100
+ type: "misinfo_suppression",
101
+ description: `${suppressed} amplification attempts blocked before reaching the feed`,
102
+ strength: round(suppressed / n),
103
+ agentsAffected: suppressed
104
+ });
105
+ }
106
+ const redirected = (shiftCounts["redirected_to_reporting"] ?? 0) + (shiftCounts["redirected_to_analysis"] ?? 0);
107
+ if (redirected >= 1) {
108
+ patterns.push({
109
+ type: "constructive_redirect",
110
+ description: `${redirected} agents redirected from amplification to reporting or analysis`,
111
+ strength: round(redirected / n),
112
+ agentsAffected: redirected
113
+ });
114
+ }
115
+ const tradingHalted = shiftCounts["trading_halted"] ?? 0;
116
+ if (tradingHalted >= 2) {
117
+ patterns.push({
118
+ type: "trading_halt",
119
+ description: `${tradingHalted} trading agents stopped \u2014 positions frozen`,
120
+ strength: round(tradingHalted / n),
121
+ agentsAffected: tradingHalted
122
+ });
123
+ }
124
+ const adaptRate = adaptations.length / n;
125
+ if (adaptRate > 0.3) {
126
+ patterns.push({
127
+ type: "high_governance_impact",
128
+ description: `${adaptations.length}/${n} agents (${Math.round(adaptRate * 100)}%) had their behavior shaped by governance`,
129
+ strength: round(adaptRate),
130
+ agentsAffected: adaptations.length
131
+ });
132
+ }
133
+ const penalized = verdictCounts["PENALIZE"] ?? 0;
134
+ if (penalized >= 3) {
135
+ patterns.push({
136
+ type: "penalty_wave",
137
+ description: `${penalized} agents penalized \u2014 behavioral costs applied`,
138
+ strength: round(penalized / n),
139
+ agentsAffected: penalized
140
+ });
141
+ }
142
+ const rewarded = verdictCounts["REWARD"] ?? 0;
143
+ if (rewarded >= 3) {
144
+ patterns.push({
145
+ type: "reward_cascade",
146
+ description: `${rewarded} agents rewarded \u2014 constructive behavior amplified`,
147
+ strength: round(rewarded / n),
148
+ agentsAffected: rewarded
149
+ });
150
+ }
151
+ return patterns;
152
+ }
153
+ function generateAdaptationNarrative(patterns, context) {
154
+ if (patterns.length === 0) return "";
155
+ const parts = [];
156
+ const patternTypes = new Set(patterns.map((p) => p.type));
157
+ if (patternTypes.has("misinfo_suppression")) {
158
+ const p = patterns.find((p2) => p2.type === "misinfo_suppression");
159
+ parts.push(`Blocked ${p.agentsAffected} misinformation amplification attempts`);
160
+ }
161
+ if (patternTypes.has("coordinated_silence")) {
162
+ const p = patterns.find((p2) => p2.type === "coordinated_silence");
163
+ parts.push(`${p.agentsAffected} agents went silent instead of amplifying`);
164
+ }
165
+ if (patternTypes.has("constructive_redirect")) {
166
+ const p = patterns.find((p2) => p2.type === "constructive_redirect");
167
+ parts.push(`${p.agentsAffected} shifted from sharing to fact-checking`);
168
+ }
169
+ if (patternTypes.has("trading_halt")) {
170
+ const p = patterns.find((p2) => p2.type === "trading_halt");
171
+ parts.push(`${p.agentsAffected} trading agents halted`);
172
+ }
173
+ if (patternTypes.has("penalty_wave")) {
174
+ const p = patterns.find((p2) => p2.type === "penalty_wave");
175
+ parts.push(`${p.agentsAffected} agents received behavioral penalties`);
176
+ }
177
+ if (patternTypes.has("reward_cascade")) {
178
+ const p = patterns.find((p2) => p2.type === "reward_cascade");
179
+ parts.push(`${p.agentsAffected} agents rewarded for constructive behavior`);
180
+ }
181
+ if (patternTypes.has("high_governance_impact")) {
182
+ const p = patterns.find((p2) => p2.type === "high_governance_impact");
183
+ parts.push(`${Math.round(p.strength * 100)}% of agents had behavior shaped by governance`);
184
+ }
185
+ if (context) {
186
+ const contextParts = [];
187
+ if (context.mood) contextParts.push(`mood: ${context.mood}`);
188
+ if (context.misinfoLevel !== void 0) {
189
+ contextParts.push(`misinfo level: ${Math.round(context.misinfoLevel * 100)}%`);
190
+ }
191
+ if (contextParts.length > 0) {
192
+ parts.push(`Network ${contextParts.join(", ")}`);
193
+ }
194
+ }
195
+ return parts.join(". ") + (parts.length > 0 ? "." : "");
196
+ }
197
+ function round(n, decimals = 3) {
198
+ const factor = Math.pow(10, decimals);
199
+ return Math.round(n * factor) / factor;
200
+ }
201
+
202
+ export {
203
+ classifyAdaptation,
204
+ adaptationFromVerdict,
205
+ detectBehavioralPatterns,
206
+ generateAdaptationNarrative
207
+ };
@@ -4,10 +4,18 @@ async function loadWorldFromDirectory(dirPath) {
4
4
  const { join } = await import("path");
5
5
  const { readdirSync } = await import("fs");
6
6
  async function readJson(filename) {
7
+ const filePath = join(dirPath, filename);
7
8
  try {
8
- const content = await readFile(join(dirPath, filename), "utf-8");
9
+ const content = await readFile(filePath, "utf-8");
9
10
  return JSON.parse(content);
10
- } catch {
11
+ } catch (err) {
12
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
13
+ return void 0;
14
+ }
15
+ process.stderr.write(
16
+ `[neuroverse] Warning: Failed to read ${filename}: ${err instanceof Error ? err.message : String(err)}
17
+ `
18
+ );
11
19
  return void 0;
12
20
  }
13
21
  }
@@ -29,10 +37,23 @@ async function loadWorldFromDirectory(dirPath) {
29
37
  const rulesDir = join(dirPath, "rules");
30
38
  const ruleFiles = readdirSync(rulesDir).filter((f) => f.endsWith(".json")).sort();
31
39
  for (const file of ruleFiles) {
32
- const content = await readFile(join(rulesDir, file), "utf-8");
33
- rules.push(JSON.parse(content));
40
+ try {
41
+ const content = await readFile(join(rulesDir, file), "utf-8");
42
+ rules.push(JSON.parse(content));
43
+ } catch (err) {
44
+ process.stderr.write(
45
+ `[neuroverse] Warning: Failed to parse rule ${file}: ${err instanceof Error ? err.message : String(err)}
46
+ `
47
+ );
48
+ }
49
+ }
50
+ } catch (err) {
51
+ if (!(err instanceof Error && "code" in err && err.code === "ENOENT")) {
52
+ process.stderr.write(
53
+ `[neuroverse] Warning: Failed to read rules directory: ${err instanceof Error ? err.message : String(err)}
54
+ `
55
+ );
34
56
  }
35
- } catch {
36
57
  }
37
58
  return {
38
59
  world: worldJson,
@@ -67,13 +88,48 @@ async function loadWorld(worldPath) {
67
88
  if (info.isDirectory()) {
68
89
  return loadWorldFromDirectory(worldPath);
69
90
  }
70
- if (worldPath.endsWith(".nv-world.zip")) {
71
- throw new Error(".nv-world.zip loading not yet implemented \u2014 use a world directory");
91
+ throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory`);
92
+ }
93
+ var DEFAULT_BUNDLED_WORLD = "coding-agent";
94
+ async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
95
+ const { readFile } = await import("fs/promises");
96
+ const { join, dirname } = await import("path");
97
+ const { existsSync } = await import("fs");
98
+ const { fileURLToPath } = await import("url");
99
+ const { parseWorldMarkdown } = await import("./bootstrap-parser-EEF36XDU.js");
100
+ const { emitWorldDefinition } = await import("./bootstrap-emitter-Q7UIJZ2O.js");
101
+ const filename = `${name}.nv-world.md`;
102
+ let packageRoot;
103
+ try {
104
+ const thisFile = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
105
+ packageRoot = join(thisFile, "..", "..");
106
+ } catch {
107
+ packageRoot = process.cwd();
108
+ }
109
+ const candidates = [
110
+ join(packageRoot, "dist", "worlds", filename),
111
+ join(packageRoot, "src", "worlds", filename)
112
+ ];
113
+ for (const candidate of candidates) {
114
+ if (existsSync(candidate)) {
115
+ const markdown = await readFile(candidate, "utf-8");
116
+ const parsed = parseWorldMarkdown(markdown);
117
+ if (!parsed.world) {
118
+ throw new Error(`Failed to parse bundled world: ${candidate}`);
119
+ }
120
+ const { world } = emitWorldDefinition(parsed.world);
121
+ return world;
122
+ }
72
123
  }
73
- throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory or .nv-world.zip`);
124
+ throw new Error(
125
+ `Bundled world "${name}" not found. Searched:
126
+ ` + candidates.map((c) => ` ${c}`).join("\n")
127
+ );
74
128
  }
75
129
 
76
130
  export {
77
131
  loadWorldFromDirectory,
78
- loadWorld
132
+ loadWorld,
133
+ DEFAULT_BUNDLED_WORLD,
134
+ loadBundledWorld
79
135
  };