@neuroverseos/governance 0.8.0 → 0.9.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.
@@ -2002,10 +2002,10 @@ __export(world_loader_exports, {
2002
2002
  });
2003
2003
  async function loadWorldFromDirectory(dirPath) {
2004
2004
  const { readFile: readFile4 } = await import("fs/promises");
2005
- const { join: join18 } = await import("path");
2006
- const { readdirSync: readdirSync10 } = await import("fs");
2005
+ const { join: join21 } = await import("path");
2006
+ const { readdirSync: readdirSync11 } = await import("fs");
2007
2007
  async function readJson(filename) {
2008
- const filePath = join18(dirPath, filename);
2008
+ const filePath = join21(dirPath, filename);
2009
2009
  try {
2010
2010
  const content = await readFile4(filePath, "utf-8");
2011
2011
  return JSON.parse(content);
@@ -2035,11 +2035,11 @@ async function loadWorldFromDirectory(dirPath) {
2035
2035
  const metadataJson = await readJson("metadata.json");
2036
2036
  const rules = [];
2037
2037
  try {
2038
- const rulesDir = join18(dirPath, "rules");
2039
- const ruleFiles = readdirSync10(rulesDir).filter((f) => f.endsWith(".json")).sort();
2038
+ const rulesDir = join21(dirPath, "rules");
2039
+ const ruleFiles = readdirSync11(rulesDir).filter((f) => f.endsWith(".json")).sort();
2040
2040
  for (const file of ruleFiles) {
2041
2041
  try {
2042
- const content = await readFile4(join18(rulesDir, file), "utf-8");
2042
+ const content = await readFile4(join21(rulesDir, file), "utf-8");
2043
2043
  rules.push(JSON.parse(content));
2044
2044
  } catch (err) {
2045
2045
  process.stderr.write(
@@ -2093,8 +2093,8 @@ async function loadWorld(worldPath) {
2093
2093
  }
2094
2094
  async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
2095
2095
  const { readFile: readFile4 } = await import("fs/promises");
2096
- const { join: join18, dirname: dirname4 } = await import("path");
2097
- const { existsSync: existsSync14 } = await import("fs");
2096
+ const { join: join21, dirname: dirname4 } = await import("path");
2097
+ const { existsSync: existsSync17 } = await import("fs");
2098
2098
  const { fileURLToPath: fileURLToPath3 } = await import("url");
2099
2099
  const { parseWorldMarkdown: parseWorldMarkdown2 } = await Promise.resolve().then(() => (init_bootstrap_parser(), bootstrap_parser_exports));
2100
2100
  const { emitWorldDefinition: emitWorldDefinition2 } = await Promise.resolve().then(() => (init_bootstrap_emitter(), bootstrap_emitter_exports));
@@ -2102,16 +2102,16 @@ async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
2102
2102
  let packageRoot;
2103
2103
  try {
2104
2104
  const thisFile = typeof __dirname !== "undefined" ? __dirname : dirname4(fileURLToPath3(import_meta.url));
2105
- packageRoot = join18(thisFile, "..", "..");
2105
+ packageRoot = join21(thisFile, "..", "..");
2106
2106
  } catch {
2107
2107
  packageRoot = process.cwd();
2108
2108
  }
2109
2109
  const candidates = [
2110
- join18(packageRoot, "dist", "worlds", filename),
2111
- join18(packageRoot, "src", "worlds", filename)
2110
+ join21(packageRoot, "dist", "worlds", filename),
2111
+ join21(packageRoot, "src", "worlds", filename)
2112
2112
  ];
2113
2113
  for (const candidate of candidates) {
2114
- if (existsSync14(candidate)) {
2114
+ if (existsSync17(candidate)) {
2115
2115
  const markdown = await readFile4(candidate, "utf-8");
2116
2116
  const parsed = parseWorldMarkdown2(markdown);
2117
2117
  if (!parsed.world) {
@@ -2141,8 +2141,8 @@ function slugify(text) {
2141
2141
  }
2142
2142
  async function addGuard(worldDir, input) {
2143
2143
  const { readFile: readFile4, writeFile: writeFile6 } = await import("fs/promises");
2144
- const { join: join18 } = await import("path");
2145
- const guardsPath = join18(worldDir, "guards.json");
2144
+ const { join: join21 } = await import("path");
2145
+ const guardsPath = join21(worldDir, "guards.json");
2146
2146
  let config;
2147
2147
  try {
2148
2148
  const raw = await readFile4(guardsPath, "utf-8");
@@ -2182,13 +2182,13 @@ async function addGuard(worldDir, input) {
2182
2182
  }
2183
2183
  async function addRule(worldDir, input) {
2184
2184
  const { readFile: readFile4, writeFile: writeFile6, mkdir: mkdir3 } = await import("fs/promises");
2185
- const { join: join18 } = await import("path");
2186
- const { readdirSync: readdirSync10 } = await import("fs");
2187
- const rulesDir = join18(worldDir, "rules");
2185
+ const { join: join21 } = await import("path");
2186
+ const { readdirSync: readdirSync11 } = await import("fs");
2187
+ const rulesDir = join21(worldDir, "rules");
2188
2188
  await mkdir3(rulesDir, { recursive: true });
2189
2189
  let nextNum = 1;
2190
2190
  try {
2191
- const existing = readdirSync10(rulesDir).filter((f) => f.match(/^rule-\d+\.json$/)).sort();
2191
+ const existing = readdirSync11(rulesDir).filter((f) => f.match(/^rule-\d+\.json$/)).sort();
2192
2192
  if (existing.length > 0) {
2193
2193
  const lastFile = existing[existing.length - 1];
2194
2194
  const match = lastFile.match(/rule-(\d+)\.json/);
@@ -2214,7 +2214,7 @@ async function addRule(worldDir, input) {
2214
2214
  effect_text: input.effects ? input.effects.map((e) => `${e.target} ${e.operation} ${e.value}`).join(", ") : "No direct effects"
2215
2215
  }
2216
2216
  };
2217
- const rulePath = join18(rulesDir, `rule-${ruleNum}.json`);
2217
+ const rulePath = join21(rulesDir, `rule-${ruleNum}.json`);
2218
2218
  await writeFile6(rulePath, JSON.stringify(rule, null, 2) + "\n");
2219
2219
  const { loadWorldFromDirectory: loadWorldFromDirectory3 } = await Promise.resolve().then(() => (init_world_loader(), world_loader_exports));
2220
2220
  const world = await loadWorldFromDirectory3(worldDir);
@@ -2230,8 +2230,8 @@ async function addRule(worldDir, input) {
2230
2230
  }
2231
2231
  async function addInvariant(worldDir, input) {
2232
2232
  const { readFile: readFile4, writeFile: writeFile6 } = await import("fs/promises");
2233
- const { join: join18 } = await import("path");
2234
- const invariantsPath = join18(worldDir, "invariants.json");
2233
+ const { join: join21 } = await import("path");
2234
+ const invariantsPath = join21(worldDir, "invariants.json");
2235
2235
  let config;
2236
2236
  try {
2237
2237
  const raw = await readFile4(invariantsPath, "utf-8");
@@ -2849,27 +2849,27 @@ ${candidates.map((c) => ` - ${c}`).join("\n")}`
2849
2849
  }
2850
2850
  async function collectMarkdownSources(inputPath) {
2851
2851
  const { stat, readFile: rf, readdir } = await import("fs/promises");
2852
- const { join: pathJoin, extname: extname4, basename: basename5 } = await import("path");
2852
+ const { join: pathJoin, extname: extname4, basename: basename6 } = await import("path");
2853
2853
  const stats = await stat(inputPath);
2854
2854
  if (stats.isFile()) {
2855
2855
  const content = await rf(inputPath, "utf-8");
2856
- return [{ filename: basename5(inputPath), content }];
2856
+ return [{ filename: basename6(inputPath), content }];
2857
2857
  }
2858
2858
  if (stats.isDirectory()) {
2859
2859
  const sources = [];
2860
- await collectDir(inputPath, sources, rf, pathJoin, extname4, basename5);
2860
+ await collectDir(inputPath, sources, rf, pathJoin, extname4, basename6);
2861
2861
  sources.sort((a, b) => a.filename.localeCompare(b.filename));
2862
2862
  return sources;
2863
2863
  }
2864
2864
  throw new Error(`Input path is neither a file nor a directory: ${inputPath}`);
2865
2865
  }
2866
- async function collectDir(dir, sources, rf, pathJoin, extname4, basename5) {
2866
+ async function collectDir(dir, sources, rf, pathJoin, extname4, basename6) {
2867
2867
  const { readdir } = await import("fs/promises");
2868
2868
  const entries = await readdir(dir, { withFileTypes: true });
2869
2869
  for (const entry of entries) {
2870
2870
  const fullPath = pathJoin(dir, entry.name);
2871
2871
  if (entry.isDirectory()) {
2872
- await collectDir(fullPath, sources, rf, pathJoin, extname4, basename5);
2872
+ await collectDir(fullPath, sources, rf, pathJoin, extname4, basename6);
2873
2873
  } else if (entry.isFile() && extname4(entry.name).toLowerCase() === ".md") {
2874
2874
  const content = await rf(fullPath, "utf-8");
2875
2875
  sources.push({ filename: entry.name, content });
@@ -3528,21 +3528,21 @@ function parseArgs2(argv) {
3528
3528
  }
3529
3529
  async function writeWorldFiles(outputDir, world) {
3530
3530
  const { writeFile: writeFile6, mkdir: mkdir3 } = await import("fs/promises");
3531
- const { join: join18 } = await import("path");
3531
+ const { join: join21 } = await import("path");
3532
3532
  await mkdir3(outputDir, { recursive: true });
3533
- await writeFile6(join18(outputDir, "world.json"), JSON.stringify(world.world, null, 2));
3534
- await writeFile6(join18(outputDir, "invariants.json"), JSON.stringify({ invariants: world.invariants }, null, 2));
3535
- await writeFile6(join18(outputDir, "assumptions.json"), JSON.stringify(world.assumptions, null, 2));
3536
- await writeFile6(join18(outputDir, "state-schema.json"), JSON.stringify(world.stateSchema, null, 2));
3537
- await writeFile6(join18(outputDir, "gates.json"), JSON.stringify(world.gates, null, 2));
3538
- await writeFile6(join18(outputDir, "outcomes.json"), JSON.stringify(world.outcomes, null, 2));
3539
- await writeFile6(join18(outputDir, "metadata.json"), JSON.stringify(world.metadata, null, 2));
3540
- const rulesDir = join18(outputDir, "rules");
3533
+ await writeFile6(join21(outputDir, "world.json"), JSON.stringify(world.world, null, 2));
3534
+ await writeFile6(join21(outputDir, "invariants.json"), JSON.stringify({ invariants: world.invariants }, null, 2));
3535
+ await writeFile6(join21(outputDir, "assumptions.json"), JSON.stringify(world.assumptions, null, 2));
3536
+ await writeFile6(join21(outputDir, "state-schema.json"), JSON.stringify(world.stateSchema, null, 2));
3537
+ await writeFile6(join21(outputDir, "gates.json"), JSON.stringify(world.gates, null, 2));
3538
+ await writeFile6(join21(outputDir, "outcomes.json"), JSON.stringify(world.outcomes, null, 2));
3539
+ await writeFile6(join21(outputDir, "metadata.json"), JSON.stringify(world.metadata, null, 2));
3540
+ const rulesDir = join21(outputDir, "rules");
3541
3541
  await mkdir3(rulesDir, { recursive: true });
3542
3542
  const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
3543
3543
  for (let i = 0; i < sortedRules.length; i++) {
3544
3544
  const ruleNum = String(i + 1).padStart(3, "0");
3545
- await writeFile6(join18(rulesDir, `rule-${ruleNum}.json`), JSON.stringify(sortedRules[i], null, 2));
3545
+ await writeFile6(join21(rulesDir, `rule-${ruleNum}.json`), JSON.stringify(sortedRules[i], null, 2));
3546
3546
  }
3547
3547
  }
3548
3548
  function write(msg) {
@@ -3557,12 +3557,12 @@ function printInsight(finding2) {
3557
3557
  async function main2(argv = process.argv.slice(2)) {
3558
3558
  try {
3559
3559
  const args = parseArgs2(argv);
3560
- const { basename: basename5 } = await import("path");
3560
+ const { basename: basename6 } = await import("path");
3561
3561
  write(`
3562
3562
  NeuroVerse World Builder
3563
3563
  `);
3564
3564
  write(`
3565
- Analyzing: ${basename5(args.inputPath)}
3565
+ Analyzing: ${basename6(args.inputPath)}
3566
3566
  `);
3567
3567
  const derivedPath = args.outputDir ? `${args.outputDir}/source.nv-world.md` : ".neuroverse/build-output.nv-world.md";
3568
3568
  const { mkdir: mkdir3 } = await import("fs/promises");
@@ -3673,9 +3673,9 @@ World source written to: ${derivedPath}
3673
3673
  try {
3674
3674
  const emitResult = emitWorldDefinition(parseResult.world);
3675
3675
  await writeWorldFiles(outputDir, emitResult.world);
3676
- const { join: join18 } = await import("path");
3676
+ const { join: join21 } = await import("path");
3677
3677
  const { copyFile } = await import("fs/promises");
3678
- const sourceDest = join18(outputDir, "source.nv-world.md");
3678
+ const sourceDest = join21(outputDir, "source.nv-world.md");
3679
3679
  if (derivedPath !== sourceDest) {
3680
3680
  await copyFile(derivedPath, sourceDest);
3681
3681
  }
@@ -5009,8 +5009,8 @@ async function main6(argv = process.argv.slice(2)) {
5009
5009
  try {
5010
5010
  const args = parseArgs6(argv);
5011
5011
  const { writeFile: writeFile6 } = await import("fs/promises");
5012
- const { existsSync: existsSync14 } = await import("fs");
5013
- if (existsSync14(args.outputPath)) {
5012
+ const { existsSync: existsSync17 } = await import("fs");
5013
+ if (existsSync17(args.outputPath)) {
5014
5014
  process.stderr.write(`File already exists: ${args.outputPath}
5015
5015
  `);
5016
5016
  process.stderr.write("Use a different --output path or remove the existing file.\n");
@@ -5868,22 +5868,22 @@ function parseArgs9(argv) {
5868
5868
  }
5869
5869
  async function writeWorldFiles2(outputDir, world) {
5870
5870
  const { writeFile: writeFile6, mkdir: mkdir3 } = await import("fs/promises");
5871
- const { join: join18 } = await import("path");
5871
+ const { join: join21 } = await import("path");
5872
5872
  await mkdir3(outputDir, { recursive: true });
5873
- await writeFile6(join18(outputDir, "world.json"), JSON.stringify(world.world, null, 2));
5874
- await writeFile6(join18(outputDir, "invariants.json"), JSON.stringify({ invariants: world.invariants }, null, 2));
5875
- await writeFile6(join18(outputDir, "assumptions.json"), JSON.stringify(world.assumptions, null, 2));
5876
- await writeFile6(join18(outputDir, "state-schema.json"), JSON.stringify(world.stateSchema, null, 2));
5877
- const rulesDir = join18(outputDir, "rules");
5873
+ await writeFile6(join21(outputDir, "world.json"), JSON.stringify(world.world, null, 2));
5874
+ await writeFile6(join21(outputDir, "invariants.json"), JSON.stringify({ invariants: world.invariants }, null, 2));
5875
+ await writeFile6(join21(outputDir, "assumptions.json"), JSON.stringify(world.assumptions, null, 2));
5876
+ await writeFile6(join21(outputDir, "state-schema.json"), JSON.stringify(world.stateSchema, null, 2));
5877
+ const rulesDir = join21(outputDir, "rules");
5878
5878
  await mkdir3(rulesDir, { recursive: true });
5879
5879
  const sortedRules = [...world.rules].sort((a, b) => a.order - b.order);
5880
5880
  for (let i = 0; i < sortedRules.length; i++) {
5881
5881
  const ruleNum = String(i + 1).padStart(3, "0");
5882
- await writeFile6(join18(rulesDir, `rule-${ruleNum}.json`), JSON.stringify(sortedRules[i], null, 2));
5882
+ await writeFile6(join21(rulesDir, `rule-${ruleNum}.json`), JSON.stringify(sortedRules[i], null, 2));
5883
5883
  }
5884
- await writeFile6(join18(outputDir, "gates.json"), JSON.stringify(world.gates, null, 2));
5885
- await writeFile6(join18(outputDir, "outcomes.json"), JSON.stringify(world.outcomes, null, 2));
5886
- await writeFile6(join18(outputDir, "metadata.json"), JSON.stringify(world.metadata, null, 2));
5884
+ await writeFile6(join21(outputDir, "gates.json"), JSON.stringify(world.gates, null, 2));
5885
+ await writeFile6(join21(outputDir, "outcomes.json"), JSON.stringify(world.outcomes, null, 2));
5886
+ await writeFile6(join21(outputDir, "metadata.json"), JSON.stringify(world.metadata, null, 2));
5887
5887
  }
5888
5888
  async function main9(argv = process.argv.slice(2)) {
5889
5889
  const startTime = performance.now();
@@ -8242,13 +8242,13 @@ function handleHealthCheck() {
8242
8242
  }
8243
8243
  async function handleListPresets(policiesDir) {
8244
8244
  const { readdir, readFile: readFile4 } = await import("fs/promises");
8245
- const { join: join18 } = await import("path");
8246
- const dir = policiesDir ?? join18(process.cwd(), "policies");
8245
+ const { join: join21 } = await import("path");
8246
+ const dir = policiesDir ?? join21(process.cwd(), "policies");
8247
8247
  const presets = [];
8248
8248
  try {
8249
8249
  const files = await readdir(dir);
8250
8250
  for (const file of files.filter((f) => f.endsWith(".txt")).sort()) {
8251
- const content = await readFile4(join18(dir, file), "utf-8");
8251
+ const content = await readFile4(join21(dir, file), "utf-8");
8252
8252
  const id = file.replace(".txt", "");
8253
8253
  const name = id.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
8254
8254
  const firstLine = content.split("\n").find((l) => l.trim().length > 0) ?? "";
@@ -8320,7 +8320,7 @@ function govern(action, world, options) {
8320
8320
  }
8321
8321
  async function writeTempWorld(dir, policyLines) {
8322
8322
  const { writeFile: writeFile6, mkdir: mkdir3 } = await import("fs/promises");
8323
- const { join: join18 } = await import("path");
8323
+ const { join: join21 } = await import("path");
8324
8324
  await mkdir3(dir, { recursive: true });
8325
8325
  const worldJson = {
8326
8326
  world_id: "demo-live",
@@ -8362,9 +8362,9 @@ async function writeTempWorld(dir, policyLines) {
8362
8362
  authoring_method: "manual-authoring"
8363
8363
  };
8364
8364
  await Promise.all([
8365
- writeFile6(join18(dir, "world.json"), JSON.stringify(worldJson, null, 2)),
8366
- writeFile6(join18(dir, "kernel.json"), JSON.stringify(kernelJson, null, 2)),
8367
- writeFile6(join18(dir, "metadata.json"), JSON.stringify(metadataJson, null, 2))
8365
+ writeFile6(join21(dir, "world.json"), JSON.stringify(worldJson, null, 2)),
8366
+ writeFile6(join21(dir, "kernel.json"), JSON.stringify(kernelJson, null, 2)),
8367
+ writeFile6(join21(dir, "metadata.json"), JSON.stringify(metadataJson, null, 2))
8368
8368
  ]);
8369
8369
  }
8370
8370
  var init_govern = __esm({
@@ -8708,10 +8708,10 @@ data: ${data}
8708
8708
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
8709
8709
  }
8710
8710
  function readBody(req) {
8711
- return new Promise((resolve10, reject) => {
8711
+ return new Promise((resolve14, reject) => {
8712
8712
  const chunks = [];
8713
8713
  req.on("data", (chunk) => chunks.push(chunk));
8714
- req.on("end", () => resolve10(Buffer.concat(chunks).toString("utf-8")));
8714
+ req.on("end", () => resolve14(Buffer.concat(chunks).toString("utf-8")));
8715
8715
  req.on("error", reject);
8716
8716
  });
8717
8717
  }
@@ -11475,9 +11475,9 @@ async function main15(argv) {
11475
11475
  }
11476
11476
  if (worldPath) {
11477
11477
  try {
11478
- const { existsSync: existsSync14 } = await import("fs");
11479
- const { join: join18 } = await import("path");
11480
- const hasWorld = existsSync14(join18(worldPath, "world.json"));
11478
+ const { existsSync: existsSync17 } = await import("fs");
11479
+ const { join: join21 } = await import("path");
11480
+ const hasWorld = existsSync17(join21(worldPath, "world.json"));
11481
11481
  checks.push({
11482
11482
  label: "World file detected",
11483
11483
  status: hasWorld ? "pass" : "fail",
@@ -11492,12 +11492,12 @@ async function main15(argv) {
11492
11492
  });
11493
11493
  }
11494
11494
  } else {
11495
- const { existsSync: existsSync14 } = await import("fs");
11496
- const { join: join18 } = await import("path");
11495
+ const { existsSync: existsSync17 } = await import("fs");
11496
+ const { join: join21 } = await import("path");
11497
11497
  const candidates = ["./world", "./.neuroverse", "./worlds"];
11498
11498
  let found;
11499
11499
  for (const dir of candidates) {
11500
- if (existsSync14(join18(dir, "world.json"))) {
11500
+ if (existsSync17(join21(dir, "world.json"))) {
11501
11501
  found = dir;
11502
11502
  break;
11503
11503
  }
@@ -12549,8 +12549,8 @@ async function deriveCommand(args) {
12549
12549
  return;
12550
12550
  }
12551
12551
  const plan = result.plan;
12552
- const { mkdirSync: mkdirSync6 } = await import("fs");
12553
- mkdirSync6(outputDir, { recursive: true });
12552
+ const { mkdirSync: mkdirSync7 } = await import("fs");
12553
+ mkdirSync7(outputDir, { recursive: true });
12554
12554
  const worldJson = {
12555
12555
  world_id: `plan_${plan.plan_id}`,
12556
12556
  name: `Derived: ${plan.objective}`,
@@ -13148,7 +13148,7 @@ async function runPipeMode(config) {
13148
13148
  `);
13149
13149
  }
13150
13150
  const MAX_BUFFER_SIZE = 1e6;
13151
- return new Promise((resolve10, reject) => {
13151
+ return new Promise((resolve14, reject) => {
13152
13152
  let buffer = "";
13153
13153
  process.stdin.setEncoding("utf-8");
13154
13154
  process.stdin.on("data", (chunk) => {
@@ -13194,7 +13194,7 @@ async function runPipeMode(config) {
13194
13194
  `[neuroverse] Session complete: ${finalState.actionsEvaluated} evaluated, ${finalState.actionsAllowed} allowed, ${finalState.actionsBlocked} blocked, ${finalState.actionsPaused} paused
13195
13195
  `
13196
13196
  );
13197
- resolve10();
13197
+ resolve14();
13198
13198
  });
13199
13199
  process.stdin.on("error", reject);
13200
13200
  });
@@ -13310,8 +13310,8 @@ ${response.content}
13310
13310
  rl2.on("close", () => {
13311
13311
  session.stop();
13312
13312
  });
13313
- return new Promise((resolve10) => {
13314
- rl2.on("close", resolve10);
13313
+ return new Promise((resolve14) => {
13314
+ rl2.on("close", resolve14);
13315
13315
  });
13316
13316
  }
13317
13317
  var SessionManager;
@@ -14422,27 +14422,27 @@ function computeWorldDiff(a, b) {
14422
14422
  }
14423
14423
  async function worldSnapshot(worldPath) {
14424
14424
  const { readdir, readFile: readFile4, mkdir: mkdir3, writeFile: writeFile6 } = await import("fs/promises");
14425
- const { join: join18 } = await import("path");
14425
+ const { join: join21 } = await import("path");
14426
14426
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
14427
- const snapshotDir = join18(worldPath, ".snapshots", timestamp);
14427
+ const snapshotDir = join21(worldPath, ".snapshots", timestamp);
14428
14428
  await mkdir3(snapshotDir, { recursive: true });
14429
14429
  const files = await readdir(worldPath);
14430
14430
  let copied = 0;
14431
14431
  for (const file of files) {
14432
14432
  if (file.endsWith(".json")) {
14433
- const content = await readFile4(join18(worldPath, file), "utf-8");
14434
- await writeFile6(join18(snapshotDir, file), content, "utf-8");
14433
+ const content = await readFile4(join21(worldPath, file), "utf-8");
14434
+ await writeFile6(join21(snapshotDir, file), content, "utf-8");
14435
14435
  copied++;
14436
14436
  }
14437
14437
  }
14438
14438
  try {
14439
- const rulesDir = join18(worldPath, "rules");
14439
+ const rulesDir = join21(worldPath, "rules");
14440
14440
  const ruleFiles = await readdir(rulesDir);
14441
- await mkdir3(join18(snapshotDir, "rules"), { recursive: true });
14441
+ await mkdir3(join21(snapshotDir, "rules"), { recursive: true });
14442
14442
  for (const file of ruleFiles) {
14443
14443
  if (file.endsWith(".json")) {
14444
- const content = await readFile4(join18(rulesDir, file), "utf-8");
14445
- await writeFile6(join18(snapshotDir, "rules", file), content, "utf-8");
14444
+ const content = await readFile4(join21(rulesDir, file), "utf-8");
14445
+ await writeFile6(join21(snapshotDir, "rules", file), content, "utf-8");
14446
14446
  copied++;
14447
14447
  }
14448
14448
  }
@@ -14455,8 +14455,8 @@ async function worldSnapshot(worldPath) {
14455
14455
  }
14456
14456
  async function worldRollback(worldPath) {
14457
14457
  const { readdir, readFile: readFile4, writeFile: writeFile6, mkdir: mkdir3 } = await import("fs/promises");
14458
- const { join: join18 } = await import("path");
14459
- const snapshotsDir = join18(worldPath, ".snapshots");
14458
+ const { join: join21 } = await import("path");
14459
+ const snapshotsDir = join21(worldPath, ".snapshots");
14460
14460
  let snapshots;
14461
14461
  try {
14462
14462
  snapshots = (await readdir(snapshotsDir)).sort();
@@ -14471,34 +14471,34 @@ async function worldRollback(worldPath) {
14471
14471
  return;
14472
14472
  }
14473
14473
  const latest = snapshots[snapshots.length - 1];
14474
- const snapshotDir = join18(snapshotsDir, latest);
14474
+ const snapshotDir = join21(snapshotsDir, latest);
14475
14475
  const backupTimestamp = "pre-rollback-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
14476
- const backupDir = join18(snapshotsDir, backupTimestamp);
14476
+ const backupDir = join21(snapshotsDir, backupTimestamp);
14477
14477
  await mkdir3(backupDir, { recursive: true });
14478
14478
  const currentFiles = await readdir(worldPath);
14479
14479
  for (const file of currentFiles) {
14480
14480
  if (file.endsWith(".json")) {
14481
- const content = await readFile4(join18(worldPath, file), "utf-8");
14482
- await writeFile6(join18(backupDir, file), content, "utf-8");
14481
+ const content = await readFile4(join21(worldPath, file), "utf-8");
14482
+ await writeFile6(join21(backupDir, file), content, "utf-8");
14483
14483
  }
14484
14484
  }
14485
14485
  const snapshotFiles = await readdir(snapshotDir);
14486
14486
  let restored = 0;
14487
14487
  for (const file of snapshotFiles) {
14488
14488
  if (file.endsWith(".json")) {
14489
- const content = await readFile4(join18(snapshotDir, file), "utf-8");
14490
- await writeFile6(join18(worldPath, file), content, "utf-8");
14489
+ const content = await readFile4(join21(snapshotDir, file), "utf-8");
14490
+ await writeFile6(join21(worldPath, file), content, "utf-8");
14491
14491
  restored++;
14492
14492
  }
14493
14493
  }
14494
14494
  try {
14495
- const rulesDir = join18(snapshotDir, "rules");
14495
+ const rulesDir = join21(snapshotDir, "rules");
14496
14496
  const ruleFiles = await readdir(rulesDir);
14497
- await mkdir3(join18(worldPath, "rules"), { recursive: true });
14497
+ await mkdir3(join21(worldPath, "rules"), { recursive: true });
14498
14498
  for (const file of ruleFiles) {
14499
14499
  if (file.endsWith(".json")) {
14500
- const content = await readFile4(join18(rulesDir, file), "utf-8");
14501
- await writeFile6(join18(worldPath, "rules", file), content, "utf-8");
14500
+ const content = await readFile4(join21(rulesDir, file), "utf-8");
14501
+ await writeFile6(join21(worldPath, "rules", file), content, "utf-8");
14502
14502
  restored++;
14503
14503
  }
14504
14504
  }
@@ -16400,27 +16400,27 @@ function closePrompts() {
16400
16400
  }
16401
16401
  function ask(question, defaultValue) {
16402
16402
  const suffix = defaultValue ? ` [${defaultValue}]` : "";
16403
- return new Promise((resolve10) => {
16403
+ return new Promise((resolve14) => {
16404
16404
  getRL().question(`
16405
16405
  ${question}${suffix}: `, (answer) => {
16406
16406
  const val = answer.trim();
16407
- resolve10(val || defaultValue || "");
16407
+ resolve14(val || defaultValue || "");
16408
16408
  });
16409
16409
  });
16410
16410
  }
16411
16411
  function confirm(question, defaultYes = true) {
16412
16412
  const hint = defaultYes ? "[Y/n]" : "[y/N]";
16413
- return new Promise((resolve10) => {
16413
+ return new Promise((resolve14) => {
16414
16414
  getRL().question(`
16415
16415
  ${question} ${hint}: `, (answer) => {
16416
16416
  const val = answer.trim().toLowerCase();
16417
- if (val === "") resolve10(defaultYes);
16418
- else resolve10(val === "y" || val === "yes");
16417
+ if (val === "") resolve14(defaultYes);
16418
+ else resolve14(val === "y" || val === "yes");
16419
16419
  });
16420
16420
  });
16421
16421
  }
16422
16422
  function choose(question, options) {
16423
- return new Promise((resolve10) => {
16423
+ return new Promise((resolve14) => {
16424
16424
  const r = getRL();
16425
16425
  r.write(`
16426
16426
  ${question}
@@ -16430,9 +16430,9 @@ function choose(question, options) {
16430
16430
  r.question(` Choice [1-${options.length}]: `, (answer) => {
16431
16431
  const idx = parseInt(answer.trim(), 10) - 1;
16432
16432
  if (idx >= 0 && idx < options.length) {
16433
- resolve10(options[idx]);
16433
+ resolve14(options[idx]);
16434
16434
  } else {
16435
- resolve10(options[0]);
16435
+ resolve14(options[0]);
16436
16436
  }
16437
16437
  });
16438
16438
  });
@@ -16901,15 +16901,15 @@ function generateWorld(state) {
16901
16901
  return { worldJson, stateSchema, guardsJson, rules, gatesJson, invariants, outcomes, metadata };
16902
16902
  }
16903
16903
  async function writeWorld(outputDir, world) {
16904
- const { mkdirSync: mkdirSync6, existsSync: existsSync14 } = await import("fs");
16904
+ const { mkdirSync: mkdirSync7, existsSync: existsSync17 } = await import("fs");
16905
16905
  const { writeFile: writeFile6 } = await import("fs/promises");
16906
- const { join: join18 } = await import("path");
16906
+ const { join: join21 } = await import("path");
16907
16907
  const files = [];
16908
- if (!existsSync14(outputDir)) mkdirSync6(outputDir, { recursive: true });
16909
- const rulesDir = join18(outputDir, "rules");
16910
- if (!existsSync14(rulesDir)) mkdirSync6(rulesDir, { recursive: true });
16908
+ if (!existsSync17(outputDir)) mkdirSync7(outputDir, { recursive: true });
16909
+ const rulesDir = join21(outputDir, "rules");
16910
+ if (!existsSync17(rulesDir)) mkdirSync7(rulesDir, { recursive: true });
16911
16911
  const writeJson = async (name, data) => {
16912
- const path = join18(outputDir, name);
16912
+ const path = join21(outputDir, name);
16913
16913
  await writeFile6(path, JSON.stringify(data, null, 2) + "\n", "utf-8");
16914
16914
  files.push(path);
16915
16915
  };
@@ -16921,7 +16921,7 @@ async function writeWorld(outputDir, world) {
16921
16921
  await writeJson("outcomes.json", world.outcomes);
16922
16922
  await writeJson("metadata.json", world.metadata);
16923
16923
  for (const rule of world.rules) {
16924
- const rulePath = join18(rulesDir, `${rule.id}.json`);
16924
+ const rulePath = join21(rulesDir, `${rule.id}.json`);
16925
16925
  await writeFile6(rulePath, JSON.stringify(rule, null, 2) + "\n", "utf-8");
16926
16926
  files.push(rulePath);
16927
16927
  }
@@ -17008,7 +17008,7 @@ async function main31(argv = process.argv.slice(2)) {
17008
17008
  }
17009
17009
  async function phaseRefine(outputDir, world) {
17010
17010
  const { writeFile: writeFile6 } = await import("fs/promises");
17011
- const { join: join18 } = await import("path");
17011
+ const { join: join21 } = await import("path");
17012
17012
  heading("Refinement: Thresholds & Collapse");
17013
17013
  const primaryMetric = world.gatesJson.viability_classification[0]?.field || "system_health";
17014
17014
  info(`
@@ -17025,7 +17025,7 @@ async function phaseRefine(outputDir, world) {
17025
17025
  if (!isNaN(parsed)) gate.value = parsed;
17026
17026
  }
17027
17027
  await writeFile6(
17028
- join18(outputDir, "gates.json"),
17028
+ join21(outputDir, "gates.json"),
17029
17029
  JSON.stringify(world.gatesJson, null, 2) + "\n",
17030
17030
  "utf-8"
17031
17031
  );
@@ -17047,7 +17047,7 @@ async function phaseRefine(outputDir, world) {
17047
17047
  result: "MODEL_COLLAPSES"
17048
17048
  };
17049
17049
  await writeFile6(
17050
- join18(outputDir, "rules", `${rule.id}.json`),
17050
+ join21(outputDir, "rules", `${rule.id}.json`),
17051
17051
  JSON.stringify(rule, null, 2) + "\n",
17052
17052
  "utf-8"
17053
17053
  );
@@ -18100,9 +18100,9 @@ async function cmdAdd(argv) {
18100
18100
  id = name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
18101
18101
  }
18102
18102
  const { readFile: readFile4, writeFile: writeFile6 } = await import("fs/promises");
18103
- const { join: join18 } = await import("path");
18103
+ const { join: join21 } = await import("path");
18104
18104
  const possiblePaths = [
18105
- join18(worldPath, "world.nv-world.md"),
18105
+ join21(worldPath, "world.nv-world.md"),
18106
18106
  worldPath
18107
18107
  ];
18108
18108
  let mdPath = "";
@@ -18123,7 +18123,7 @@ async function cmdAdd(argv) {
18123
18123
  const files = await readdir(worldPath);
18124
18124
  const mdFile = files.find((f) => f.endsWith(".nv-world.md"));
18125
18125
  if (mdFile) {
18126
- mdPath = join18(worldPath, mdFile);
18126
+ mdPath = join21(worldPath, mdFile);
18127
18127
  mdContent = await readFile4(mdPath, "utf-8");
18128
18128
  }
18129
18129
  } catch {
@@ -18795,6 +18795,15 @@ var init_worldmodel_parser = __esm({
18795
18795
  });
18796
18796
 
18797
18797
  // src/engine/worldmodel-compiler.ts
18798
+ var worldmodel_compiler_exports = {};
18799
+ __export(worldmodel_compiler_exports, {
18800
+ compileWorldModel: () => compileWorldModel,
18801
+ emitContextsConfig: () => emitContextsConfig,
18802
+ emitLensSuggestions: () => emitLensSuggestions,
18803
+ emitOverlapMap: () => emitOverlapMap,
18804
+ emitSignalSchema: () => emitSignalSchema,
18805
+ emitWorldMarkdown: () => emitWorldMarkdown
18806
+ });
18798
18807
  function toSnakeCase(text) {
18799
18808
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
18800
18809
  }
@@ -19128,6 +19137,207 @@ var init_worldmodel_compiler = __esm({
19128
19137
  }
19129
19138
  });
19130
19139
 
19140
+ // src/cli/worldmodel-create.ts
19141
+ var worldmodel_create_exports = {};
19142
+ __export(worldmodel_create_exports, {
19143
+ askQuestions: () => askQuestions,
19144
+ saveWorldmodel: () => saveWorldmodel,
19145
+ structureWorldmodel: () => structureWorldmodel
19146
+ });
19147
+ async function askQuestions() {
19148
+ const rl2 = (0, import_readline.createInterface)({
19149
+ input: process.stdin,
19150
+ output: process.stderr
19151
+ // questions to stderr so stdout stays clean
19152
+ });
19153
+ const answers = {};
19154
+ process.stderr.write("\n");
19155
+ process.stderr.write(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n");
19156
+ process.stderr.write(" \u2551 NeuroVerseOS \u2014 Build your thinking constitution \u2551\n");
19157
+ process.stderr.write(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n");
19158
+ process.stderr.write("\n");
19159
+ process.stderr.write(" Answer these questions in your own words.\n");
19160
+ process.stderr.write(" There are no wrong answers \u2014 just say what you mean.\n");
19161
+ process.stderr.write(" The AI will structure your answers into a worldmodel.\n\n");
19162
+ for (const q of QUESTIONS) {
19163
+ const answer = await new Promise((resolve14) => {
19164
+ process.stderr.write(` \x1B[1m${q.question}\x1B[0m
19165
+ `);
19166
+ process.stderr.write(` \x1B[2m${q.placeholder}\x1B[0m
19167
+ `);
19168
+ rl2.question(" > ", (ans) => {
19169
+ process.stderr.write("\n");
19170
+ resolve14(ans.trim());
19171
+ });
19172
+ });
19173
+ answers[q.id] = answer;
19174
+ }
19175
+ rl2.close();
19176
+ return answers;
19177
+ }
19178
+ async function structureWorldmodel(answers, apiKey) {
19179
+ const prompt = buildStructuringPrompt(answers);
19180
+ const res = await fetch("https://api.anthropic.com/v1/messages", {
19181
+ method: "POST",
19182
+ headers: {
19183
+ "x-api-key": apiKey,
19184
+ "anthropic-version": "2023-06-01",
19185
+ "content-type": "application/json"
19186
+ },
19187
+ body: JSON.stringify({
19188
+ model: "claude-sonnet-4-20250514",
19189
+ max_tokens: 4096,
19190
+ system: "You are a behavioral model architect. You take conversational answers about an organization's values, purpose, and priorities, and structure them into a precise .worldmodel.md file that follows the NeuroVerseOS three-layer format. Output ONLY the markdown file content, nothing else.",
19191
+ messages: [{ role: "user", content: prompt }]
19192
+ })
19193
+ });
19194
+ if (!res.ok) {
19195
+ throw new Error(`AI structuring failed: ${res.status}`);
19196
+ }
19197
+ const data = await res.json();
19198
+ const text = data.content?.filter((c) => c.type === "text").map((c) => c.text ?? "").join("");
19199
+ if (!text) throw new Error("AI returned no content");
19200
+ return text.replace(/^```markdown\n?/, "").replace(/\n?```$/, "").trim();
19201
+ }
19202
+ function buildStructuringPrompt(answers) {
19203
+ return `Structure these conversational answers into a .worldmodel.md file.
19204
+
19205
+ The file MUST follow this exact three-layer format:
19206
+
19207
+ ---
19208
+ name: ${answers.name}
19209
+ version: 1.0.0
19210
+ ---
19211
+
19212
+ # Core Model Geometry
19213
+
19214
+ ## Mission
19215
+ (from the mission answer)
19216
+
19217
+ ## Domains
19218
+ (2-4 domains from the domains answer, each with:)
19219
+ ### Domain Name
19220
+ #### Skills (8-10 skills per domain, inferred from the answers)
19221
+ #### Values (3-4 values per domain, drawn from the non-negotiables + mission)
19222
+
19223
+ ## Overlap Effects
19224
+ (from the overlaps answer, formatted as: Domain A + Domain B = Emergent State)
19225
+
19226
+ ## Center Identity
19227
+ (from the center answer)
19228
+
19229
+ # Contextual Modifiers
19230
+
19231
+ ## Authority Layers
19232
+ (infer 4-5 authority levels appropriate to this organization)
19233
+
19234
+ ## Spatial Contexts
19235
+ (infer 4-5 contexts where behavior happens)
19236
+
19237
+ ## Interpretation Rules
19238
+ (infer 3-5 rules about how context changes meaning)
19239
+
19240
+ # Evolution Layer
19241
+
19242
+ ## Aligned Behaviors
19243
+ (from the success answer, expanded to 5-8 items)
19244
+
19245
+ ## Drift Behaviors
19246
+ (from the drift answer, expanded to 5-8 items)
19247
+
19248
+ ## Signals
19249
+ (infer 5-7 observable signals from the answers, snake_case)
19250
+
19251
+ ## Decision Priorities
19252
+ (from the priorities answer, formatted as: preferred > secondary)
19253
+
19254
+ ## Evolution Conditions
19255
+ (infer 3-5 conditions for when the model should adapt)
19256
+
19257
+ HERE ARE THE ANSWERS:
19258
+
19259
+ Name: ${answers.name}
19260
+
19261
+ Mission: ${answers.mission}
19262
+
19263
+ Domains: ${answers.domains}
19264
+
19265
+ Overlaps: ${answers.overlaps}
19266
+
19267
+ Center identity: ${answers.center}
19268
+
19269
+ Non-negotiables: ${answers.nonnegotiables}
19270
+
19271
+ Success looks like: ${answers.success}
19272
+
19273
+ Drift looks like: ${answers.drift}
19274
+
19275
+ Priorities: ${answers.priorities}
19276
+
19277
+ Output ONLY the .worldmodel.md content. No explanation. No commentary. Just the file.`;
19278
+ }
19279
+ function saveWorldmodel(content, outputPath) {
19280
+ const resolved = (0, import_path12.resolve)(outputPath);
19281
+ (0, import_fs11.writeFileSync)(resolved, content, "utf-8");
19282
+ return resolved;
19283
+ }
19284
+ var import_readline, import_fs11, import_path12, QUESTIONS;
19285
+ var init_worldmodel_create = __esm({
19286
+ "src/cli/worldmodel-create.ts"() {
19287
+ "use strict";
19288
+ import_readline = require("readline");
19289
+ import_fs11 = require("fs");
19290
+ import_path12 = require("path");
19291
+ QUESTIONS = [
19292
+ {
19293
+ id: "name",
19294
+ question: "What should we call this model? (Your name, your org, your project)",
19295
+ placeholder: 'e.g., "Kirsten", "Auki", "My Startup"'
19296
+ },
19297
+ {
19298
+ id: "mission",
19299
+ question: "In one or two sentences \u2014 what does this system exist to do? Not a slogan. The real purpose.",
19300
+ placeholder: 'e.g., "Protect human thinking while expanding cognitive capability through AI"'
19301
+ },
19302
+ {
19303
+ id: "domains",
19304
+ question: "What are the 2-3 big areas of focus? Not departments \u2014 the major kinds of work that matter most. Separate with commas.",
19305
+ placeholder: 'e.g., "Safety and boundaries, Individual authority, AI as cognitive extension"'
19306
+ },
19307
+ {
19308
+ id: "overlaps",
19309
+ question: "When those areas work well TOGETHER, what does that feel like? Name a feeling for each pair.",
19310
+ placeholder: 'e.g., "Safety + Authority = Trust, Authority + AI = Possibility"'
19311
+ },
19312
+ {
19313
+ id: "center",
19314
+ question: "When EVERYTHING is aligned \u2014 all areas working together \u2014 what does the system become? One name or phrase.",
19315
+ placeholder: 'e.g., "The Sovereign Conduit", "Collective Vanguard Leader"'
19316
+ },
19317
+ {
19318
+ id: "nonnegotiables",
19319
+ question: "What's absolutely non-negotiable? What would you walk away over? List a few.",
19320
+ placeholder: 'e.g., "Humans retain authority over thinking. AI extends, never replaces. People can always leave."'
19321
+ },
19322
+ {
19323
+ id: "success",
19324
+ question: `What does success look like in action? What would you point at and say "that's what I mean"?`,
19325
+ placeholder: 'e.g., "Someone maintaining clear authorship of decisions even when AI contributed"'
19326
+ },
19327
+ {
19328
+ id: "drift",
19329
+ question: "What does drift look like? What would worry you if you saw it happening?",
19330
+ placeholder: 'e.g., "Decision ownership quietly shifting to AI without explicit delegation"'
19331
+ },
19332
+ {
19333
+ id: "priorities",
19334
+ question: 'When tradeoffs appear, what wins? Give a few "X over Y" pairs.',
19335
+ placeholder: 'e.g., "Safety over speed, sovereignty over convenience, diversity over uniformity"'
19336
+ }
19337
+ ];
19338
+ }
19339
+ });
19340
+
19131
19341
  // src/cli/worldmodel.ts
19132
19342
  var worldmodel_exports = {};
19133
19343
  __export(worldmodel_exports, {
@@ -19164,8 +19374,8 @@ function formatIssue(issue) {
19164
19374
  return ` ${color}${icon}${RESET2} [${issue.section}${lineRef}] ${issue.message}`;
19165
19375
  }
19166
19376
  async function readSourceFile(inputPath) {
19167
- const fullPath = (0, import_path12.resolve)(inputPath);
19168
- if (!(0, import_fs11.existsSync)(fullPath)) {
19377
+ const fullPath = (0, import_path13.resolve)(inputPath);
19378
+ if (!(0, import_fs12.existsSync)(fullPath)) {
19169
19379
  process.stderr.write(`File not found: ${fullPath}
19170
19380
  `);
19171
19381
  process.exit(3);
@@ -19189,30 +19399,145 @@ async function cmdInit(argv) {
19189
19399
  const args = parseArgs26(argv);
19190
19400
  if (args.help) {
19191
19401
  process.stdout.write(
19192
- 'neuroverse worldmodel init \u2014 Scaffold a new .worldmodel.md template\n\nOptions:\n --name <name> Model name (default: "My Behavioral Model")\n --output <path> Output path (default: ./model.worldmodel.md)\n'
19402
+ 'neuroverse worldmodel init \u2014 Create a new behavioral model\n\nWith ANTHROPIC_API_KEY set:\n Interactive \u2014 answers questions, AI structures your worldmodel.\n Your natural process: talk \u2192 structure \u2192 refine.\n\nWithout ANTHROPIC_API_KEY:\n Template \u2014 generates a scaffold you fill in manually.\n\nOptions:\n --name <name> Model name (default: "My Behavioral Model")\n --output <path> Output path (default: ./model.worldmodel.md)\n --template Force template mode even with API key set\n'
19193
19403
  );
19194
19404
  return;
19195
19405
  }
19196
19406
  const modelName = args.name || "My Behavioral Model";
19197
- const outputPath = (0, import_path12.resolve)(
19407
+ const outputPath = (0, import_path13.resolve)(
19198
19408
  args.output || `./${toFileName(modelName)}.worldmodel.md`
19199
19409
  );
19200
- if ((0, import_fs11.existsSync)(outputPath)) {
19410
+ if ((0, import_fs12.existsSync)(outputPath)) {
19201
19411
  process.stderr.write(`File already exists: ${outputPath}
19202
19412
  `);
19203
19413
  process.stderr.write("Use --output to specify a different path.\n");
19204
19414
  process.exit(1);
19205
19415
  }
19416
+ const apiKey = process.env.ANTHROPIC_API_KEY;
19417
+ const forceTemplate = argv.includes("--template");
19418
+ if (apiKey && !forceTemplate && process.stdin.isTTY) {
19419
+ const { askQuestions: askQuestions2, structureWorldmodel: structureWorldmodel2, saveWorldmodel: saveWorldmodel2 } = await Promise.resolve().then(() => (init_worldmodel_create(), worldmodel_create_exports));
19420
+ process.stderr.write(`
19421
+ `);
19422
+ const answers = await askQuestions2();
19423
+ process.stderr.write(`${DIM2}Structuring your worldmodel...${RESET2}
19424
+ `);
19425
+ try {
19426
+ const content = await structureWorldmodel2(answers, apiKey);
19427
+ const dir2 = (0, import_path13.dirname)(outputPath);
19428
+ if (!(0, import_fs12.existsSync)(dir2)) {
19429
+ await (0, import_promises6.mkdir)(dir2, { recursive: true });
19430
+ }
19431
+ saveWorldmodel2(content, outputPath);
19432
+ process.stderr.write(`
19433
+ ${GREEN2}Created${RESET2} ${outputPath}
19434
+ `);
19435
+ process.stderr.write(
19436
+ `${DIM2}Review the file, then run: neuroverse worldmodel validate ${(0, import_path13.basename)(outputPath)}${RESET2}
19437
+ `
19438
+ );
19439
+ try {
19440
+ const validateResult = parseWorldModel(content);
19441
+ if (validateResult.model) {
19442
+ const m = validateResult.model;
19443
+ process.stderr.write(
19444
+ `${DIM2} Domains: ${m.geometry.domains.length} Overlaps: ${m.geometry.overlapEffects.length} Signals: ${m.evolution.signals.length}${RESET2}
19445
+ `
19446
+ );
19447
+ }
19448
+ const errors = validateResult.issues.filter((i) => i.severity === "error");
19449
+ if (errors.length > 0) {
19450
+ process.stderr.write(
19451
+ `
19452
+ ${YELLOW2}Validation found ${errors.length} issue${errors.length > 1 ? "s" : ""} \u2014 review and fix:${RESET2}
19453
+ `
19454
+ );
19455
+ for (const issue of errors) {
19456
+ process.stderr.write(` ${formatIssue(issue)}
19457
+ `);
19458
+ }
19459
+ } else {
19460
+ process.stderr.write(`${GREEN2}Validates cleanly!${RESET2}
19461
+ `);
19462
+ try {
19463
+ if (!validateResult.model) throw new Error("no model");
19464
+ const { compileWorldModel: compileWorldModel2 } = await Promise.resolve().then(() => (init_worldmodel_compiler(), worldmodel_compiler_exports));
19465
+ const compiled = compileWorldModel2(validateResult.model);
19466
+ const outDir = (0, import_path13.dirname)(outputPath);
19467
+ const baseName = (0, import_path13.basename)(outputPath).replace(/\.worldmodel\.md$/, "");
19468
+ const worldPath = (0, import_path13.join)(outDir, `${baseName}.nv-world.md`);
19469
+ await (0, import_promises6.writeFile)(worldPath, compiled.worldMarkdown, "utf-8");
19470
+ const signalsPath = (0, import_path13.join)(outDir, "signals.json");
19471
+ await (0, import_promises6.writeFile)(signalsPath, JSON.stringify(compiled.signalSchema, null, 2), "utf-8");
19472
+ const overlapsPath = (0, import_path13.join)(outDir, "overlaps.json");
19473
+ await (0, import_promises6.writeFile)(overlapsPath, JSON.stringify(compiled.overlapMap, null, 2), "utf-8");
19474
+ const contextsPath = (0, import_path13.join)(outDir, "contexts.json");
19475
+ await (0, import_promises6.writeFile)(contextsPath, JSON.stringify(compiled.contextsConfig, null, 2), "utf-8");
19476
+ const lensesPath = (0, import_path13.join)(outDir, "lenses.json");
19477
+ await (0, import_promises6.writeFile)(lensesPath, JSON.stringify(compiled.lensSuggestions, null, 2), "utf-8");
19478
+ process.stderr.write(`
19479
+ ${GREEN2}Compiled!${RESET2} Token-optimized artifacts:
19480
+ `);
19481
+ process.stderr.write(`${DIM2} ${worldPath}${RESET2}
19482
+ `);
19483
+ process.stderr.write(`${DIM2} ${signalsPath}${RESET2}
19484
+ `);
19485
+ process.stderr.write(`${DIM2} ${overlapsPath}${RESET2}
19486
+ `);
19487
+ process.stderr.write(`${DIM2} ${contextsPath}${RESET2}
19488
+ `);
19489
+ process.stderr.write(`${DIM2} ${lensesPath}${RESET2}
19490
+ `);
19491
+ process.stderr.write(`
19492
+ ${DIM2}Source: ${outputPath} (readable, editable)${RESET2}
19493
+ `);
19494
+ process.stderr.write(`${DIM2}Compiled: ready for Radiant \u2014 token-optimized, no prose overhead.${RESET2}
19495
+ `);
19496
+ } catch {
19497
+ process.stderr.write(
19498
+ `${DIM2}Auto-compile skipped \u2014 run 'neuroverse worldmodel build ${(0, import_path13.basename)(outputPath)}' manually.${RESET2}
19499
+ `
19500
+ );
19501
+ }
19502
+ }
19503
+ } catch {
19504
+ }
19505
+ } catch (err) {
19506
+ process.stderr.write(`${RED}Error:${RESET2} ${err}
19507
+ `);
19508
+ process.stderr.write(
19509
+ `${DIM2}Falling back to template mode.${RESET2}
19510
+
19511
+ `
19512
+ );
19513
+ const template2 = generateScaffold(modelName);
19514
+ const dir2 = (0, import_path13.dirname)(outputPath);
19515
+ if (!(0, import_fs12.existsSync)(dir2)) {
19516
+ await (0, import_promises6.mkdir)(dir2, { recursive: true });
19517
+ }
19518
+ await (0, import_promises6.writeFile)(outputPath, template2, "utf-8");
19519
+ process.stderr.write(`${GREEN2}Created${RESET2} ${outputPath} (template)
19520
+ `);
19521
+ }
19522
+ return;
19523
+ }
19524
+ if (!apiKey && !forceTemplate) {
19525
+ process.stderr.write(
19526
+ `${DIM2}Tip: Set ANTHROPIC_API_KEY for the guided experience \u2014 AI asks you questions and creates your worldmodel.${RESET2}
19527
+
19528
+ `
19529
+ );
19530
+ }
19206
19531
  const template = generateScaffold(modelName);
19207
- const dir = (0, import_path12.dirname)(outputPath);
19208
- if (!(0, import_fs11.existsSync)(dir)) {
19532
+ const dir = (0, import_path13.dirname)(outputPath);
19533
+ if (!(0, import_fs12.existsSync)(dir)) {
19209
19534
  await (0, import_promises6.mkdir)(dir, { recursive: true });
19210
19535
  }
19211
19536
  await (0, import_promises6.writeFile)(outputPath, template, "utf-8");
19212
19537
  process.stderr.write(`${GREEN2}Created${RESET2} ${outputPath}
19213
19538
  `);
19214
19539
  process.stderr.write(
19215
- `${DIM2}Edit the template, then run: neuroverse worldmodel validate ${(0, import_path12.basename)(outputPath)}${RESET2}
19540
+ `${DIM2}Edit the template, then run: neuroverse worldmodel validate ${(0, import_path13.basename)(outputPath)}${RESET2}
19216
19541
  `
19217
19542
  );
19218
19543
  }
@@ -19643,17 +19968,17 @@ async function cmdBuild(argv) {
19643
19968
  process.stderr.write("\n");
19644
19969
  }
19645
19970
  const output = compileWorldModel(model);
19646
- const outputDir = (0, import_path12.resolve)(
19971
+ const outputDir = (0, import_path13.resolve)(
19647
19972
  args.output || `.neuroverse/worldmodels/${model.frontmatter.model_id}/`
19648
19973
  );
19649
- if (!(0, import_fs11.existsSync)(outputDir)) {
19974
+ if (!(0, import_fs12.existsSync)(outputDir)) {
19650
19975
  await (0, import_promises6.mkdir)(outputDir, { recursive: true });
19651
19976
  }
19652
- const worldPath = (0, import_path12.join)(outputDir, `${model.frontmatter.model_id}.nv-world.md`);
19653
- const signalsPath = (0, import_path12.join)(outputDir, "signals.json");
19654
- const overlapsPath = (0, import_path12.join)(outputDir, "overlaps.json");
19655
- const contextsPath = (0, import_path12.join)(outputDir, "contexts.json");
19656
- const lensesPath = (0, import_path12.join)(outputDir, "lenses.json");
19977
+ const worldPath = (0, import_path13.join)(outputDir, `${model.frontmatter.model_id}.nv-world.md`);
19978
+ const signalsPath = (0, import_path13.join)(outputDir, "signals.json");
19979
+ const overlapsPath = (0, import_path13.join)(outputDir, "overlaps.json");
19980
+ const contextsPath = (0, import_path13.join)(outputDir, "contexts.json");
19981
+ const lensesPath = (0, import_path13.join)(outputDir, "lenses.json");
19657
19982
  await Promise.all([
19658
19983
  (0, import_promises6.writeFile)(worldPath, output.worldMarkdown, "utf-8"),
19659
19984
  (0, import_promises6.writeFile)(signalsPath, JSON.stringify(output.signalSchema, null, 2) + "\n", "utf-8"),
@@ -19685,7 +20010,7 @@ async function cmdBuild(argv) {
19685
20010
  `);
19686
20011
  process.stderr.write(` ${BOLD2}Output:${RESET2} ${outputDir}/
19687
20012
  `);
19688
- process.stderr.write(` ${(0, import_path12.basename)(worldPath)}${DIM2} \u2014 executable world${RESET2}
20013
+ process.stderr.write(` ${(0, import_path13.basename)(worldPath)}${DIM2} \u2014 executable world${RESET2}
19689
20014
  `);
19690
20015
  process.stderr.write(` signals.json${DIM2} \u2014 signal schema${RESET2}
19691
20016
  `);
@@ -19721,9 +20046,9 @@ async function cmdEmitWorld(argv) {
19721
20046
  const { model } = await loadAndParse(args.inputPath);
19722
20047
  const markdown = emitWorldMarkdown(model);
19723
20048
  if (args.output) {
19724
- const dir = (0, import_path12.dirname)((0, import_path12.resolve)(args.output));
19725
- if (!(0, import_fs11.existsSync)(dir)) await (0, import_promises6.mkdir)(dir, { recursive: true });
19726
- await (0, import_promises6.writeFile)((0, import_path12.resolve)(args.output), markdown, "utf-8");
20049
+ const dir = (0, import_path13.dirname)((0, import_path13.resolve)(args.output));
20050
+ if (!(0, import_fs12.existsSync)(dir)) await (0, import_promises6.mkdir)(dir, { recursive: true });
20051
+ await (0, import_promises6.writeFile)((0, import_path13.resolve)(args.output), markdown, "utf-8");
19727
20052
  process.stderr.write(`${GREEN2}Written${RESET2} ${args.output}
19728
20053
  `);
19729
20054
  } else {
@@ -19814,13 +20139,13 @@ async function main33(argv = process.argv.slice(2)) {
19814
20139
  process.exit(1);
19815
20140
  }
19816
20141
  }
19817
- var import_promises6, import_fs11, import_path12, BOLD2, DIM2, CYAN2, GREEN2, YELLOW2, RED, MAGENTA2, RESET2, USAGE9;
20142
+ var import_promises6, import_fs12, import_path13, BOLD2, DIM2, CYAN2, GREEN2, YELLOW2, RED, MAGENTA2, RESET2, USAGE9;
19818
20143
  var init_worldmodel = __esm({
19819
20144
  "src/cli/worldmodel.ts"() {
19820
20145
  "use strict";
19821
20146
  import_promises6 = require("fs/promises");
19822
- import_fs11 = require("fs");
19823
- import_path12 = require("path");
20147
+ import_fs12 = require("fs");
20148
+ import_path13 = require("path");
19824
20149
  init_worldmodel_parser();
19825
20150
  init_worldmodel_compiler();
19826
20151
  BOLD2 = "\x1B[1m";
@@ -20292,13 +20617,300 @@ var init_auki_builder = __esm({
20292
20617
  }
20293
20618
  });
20294
20619
 
20620
+ // src/radiant/lenses/sovereign-conduit.ts
20621
+ function sovereignConduitRewrite(pattern) {
20622
+ if (pattern.evidence.cited_invariant) {
20623
+ return {
20624
+ ...pattern,
20625
+ framing: "non-negotiable rule tested",
20626
+ emphasis: "name the rule, name who it protects, name what would happen without it",
20627
+ compress: false
20628
+ // Sovereign Conduit is warm, not compressed
20629
+ };
20630
+ }
20631
+ if (pattern.type === "candidate") {
20632
+ return {
20633
+ ...pattern,
20634
+ framing: "something new noticed",
20635
+ emphasis: "explain what was seen in everyday language, ask whether it matters",
20636
+ compress: false
20637
+ };
20638
+ }
20639
+ return {
20640
+ ...pattern,
20641
+ framing: "what this means for the people in the system",
20642
+ emphasis: "humanity + agency + learning",
20643
+ compress: false
20644
+ };
20645
+ }
20646
+ var SOVEREIGN_CONDUIT_FRAME, SOVEREIGN_CONDUIT_VOCABULARY, SOVEREIGN_CONDUIT_VOICE, SOVEREIGN_CONDUIT_FORBIDDEN, SOVEREIGN_CONDUIT_PREFERRED, SOVEREIGN_CONDUIT_STRATEGIC, SOVEREIGN_CONDUIT_EXEMPLARS, sovereignConduitLens;
20647
+ var init_sovereign_conduit = __esm({
20648
+ "src/radiant/lenses/sovereign-conduit.ts"() {
20649
+ "use strict";
20650
+ SOVEREIGN_CONDUIT_FRAME = {
20651
+ domains: [
20652
+ "stewardship",
20653
+ "agency",
20654
+ "integration"
20655
+ ],
20656
+ overlaps: [
20657
+ {
20658
+ domains: ["stewardship", "agency"],
20659
+ emergent_state: "Trust",
20660
+ description: "I am safe to be myself. When the system protects AND preserves individual authority, trust emerges \u2014 the feeling that you can think freely because someone is watching the boundaries."
20661
+ },
20662
+ {
20663
+ domains: ["agency", "integration"],
20664
+ emergent_state: "Possibility",
20665
+ description: "My thinking can expand. When individual authority is preserved AND AI extends cognitive capability, possibility opens \u2014 the feeling that you can reach further without losing yourself."
20666
+ },
20667
+ {
20668
+ domains: ["integration", "stewardship"],
20669
+ emergent_state: "Responsibility",
20670
+ description: "Power is used with care. When AI extends capability AND the system protects integrity, responsibility emerges \u2014 the feeling that expansion comes with guardrails, not recklessness."
20671
+ }
20672
+ ],
20673
+ center_identity: "The Sovereign Conduit",
20674
+ evaluation_questions: [
20675
+ "Is the human maintaining authority over their decisions, or is decision ownership quietly shifting to the AI?",
20676
+ "Is the AI extending thinking, or is it replacing thinking? Look for the difference: extension means the human understands and owns the output. Replacement means they accept it without engaging.",
20677
+ "Are the boundaries between human thinking and AI output clear and visible, or are they blurring?",
20678
+ "Is diversity of thought preserved? Are people thinking differently from each other, or is the system funneling everyone into the same patterns?",
20679
+ "Would you feel safe letting a child learn in this system? If not, what specifically makes it unsafe?",
20680
+ "If this felt wrong, could you leave? Is the exit real or theoretical?"
20681
+ ],
20682
+ scoring_rubric: "For any activity, ask: is the human still the author of their decisions? Is the AI helping them think further, or thinking for them? Are the rules of this space clear, fair, and safe \u2014 like the rules at a good friend's house? When something feels off, name the feeling first, then the mechanism. Use everyday language. If a non-technical person couldn't understand the observation, rephrase it until they could.",
20683
+ domain_skills: {
20684
+ "stewardship": [
20685
+ "boundary setting",
20686
+ "risk awareness",
20687
+ "ethical judgment",
20688
+ "system protection",
20689
+ "conflict stabilization",
20690
+ "responsibility signaling",
20691
+ "harm detection",
20692
+ "constraint design"
20693
+ ],
20694
+ "agency": [
20695
+ "independent thinking",
20696
+ "decision ownership",
20697
+ "self-trust",
20698
+ "value clarity",
20699
+ "cognitive resistance",
20700
+ "identity anchoring",
20701
+ "perspective holding",
20702
+ "authentic expression"
20703
+ ],
20704
+ "integration": [
20705
+ "AI collaboration",
20706
+ "cognitive expansion",
20707
+ "prompt framing",
20708
+ "insight synthesis",
20709
+ "signal interpretation",
20710
+ "tool fluency",
20711
+ "co-creation",
20712
+ "iterative thinking"
20713
+ ]
20714
+ },
20715
+ output_translation: {
20716
+ never_surface_in_output: [
20717
+ "Stewardship",
20718
+ "Agency",
20719
+ "Integration"
20720
+ ],
20721
+ surface_freely: [
20722
+ "Trust",
20723
+ "Possibility",
20724
+ "Responsibility",
20725
+ "Sovereign Conduit"
20726
+ ],
20727
+ translation_examples: [
20728
+ {
20729
+ internal_reasoning: "Stewardship is strong",
20730
+ external_expression: "the boundaries are clear and the system feels safe to operate inside"
20731
+ },
20732
+ {
20733
+ internal_reasoning: "Agency is weakening",
20734
+ external_expression: "decision ownership is quietly shifting \u2014 the human is accepting AI output without engaging with it"
20735
+ },
20736
+ {
20737
+ internal_reasoning: "Integration is high but Stewardship is low",
20738
+ external_expression: "the AI is expanding capability fast, but nobody is watching the guardrails \u2014 that's power without responsibility"
20739
+ }
20740
+ ]
20741
+ }
20742
+ };
20743
+ SOVEREIGN_CONDUIT_VOCABULARY = {
20744
+ proper_nouns: [
20745
+ "NeuroVerseOS",
20746
+ "Sovereign Conduit",
20747
+ "LifeOS",
20748
+ "CyberOS",
20749
+ "NeuroverseOS"
20750
+ ],
20751
+ preferred: {
20752
+ "worldmodel": "thinking constitution",
20753
+ "invariant": "non-negotiable rule",
20754
+ "governance": "the rules of the space",
20755
+ "alignment": "how well the work matches what was declared",
20756
+ "drift": "quiet shift away from what was intended",
20757
+ "signal": "something observable",
20758
+ "evidence gate": "how much we need to see before we speak",
20759
+ "actor domain": "who did the work \u2014 a person, an AI, or both together",
20760
+ "rendering lens": "how the system speaks",
20761
+ "candidate pattern": "something noticed but not yet named as important",
20762
+ "cognitive liberty": "your right to think for yourself",
20763
+ "homogenization": "everyone being funneled into the same patterns"
20764
+ },
20765
+ architecture: [
20766
+ "thinking constitution",
20767
+ "thinking space",
20768
+ "cognitive extension",
20769
+ "behavioral model",
20770
+ "governance frame",
20771
+ "world file",
20772
+ "cocoon"
20773
+ ],
20774
+ economic: [],
20775
+ framing: [
20776
+ "humanity first",
20777
+ "in constant learning",
20778
+ "in shared teaching",
20779
+ "extension not replacement",
20780
+ "safe to think freely",
20781
+ "the rules of this house",
20782
+ "sovereign over your own thinking",
20783
+ "idea calculator",
20784
+ "Spock in your life",
20785
+ "Jarvis in your life",
20786
+ "funneling into fields",
20787
+ "diversity of thought",
20788
+ "thinking for yourself"
20789
+ ],
20790
+ jargon_translations: {
20791
+ "worldmodel": "thinking constitution",
20792
+ "invariant": "non-negotiable rule",
20793
+ "canonical pattern": "something we're tracking by name",
20794
+ "candidate pattern": "something noticed but not yet tracked",
20795
+ "evidence gate": "how much we need to see before we speak up",
20796
+ "signal extraction": "reading what happened",
20797
+ "alignment score": "how well the work matches what was declared",
20798
+ "actor domain": "who did this \u2014 a person, an AI, or both",
20799
+ "presence-based averaging": "only counting what actually happened",
20800
+ "drift detection": "noticing when things quietly shift",
20801
+ "INSUFFICIENT_EVIDENCE": "not enough to say yet",
20802
+ "UNAVAILABLE": "can't measure this yet",
20803
+ "rendering lens": "how the system speaks to you"
20804
+ }
20805
+ };
20806
+ SOVEREIGN_CONDUIT_VOICE = {
20807
+ register: "warm, accessible, teaching. Like a thoughtful parent explaining how the world works \u2014 not talking down, but making the complex feel natural. Use everyday analogies. Name emotions. If a non-technical person couldn't understand the output, it's wrong.",
20808
+ active_voice: "preferred",
20809
+ specificity: "preferred",
20810
+ hype_vocabulary: "forbidden",
20811
+ hedging: "discouraged",
20812
+ playfulness: "allowed",
20813
+ close_with_strategic_frame: "preferred",
20814
+ punchline_move: "sparing",
20815
+ honesty_about_failure: "required",
20816
+ output_translation: `Reason internally through the three-domain frame (Stewardship, Agency, Integration). Express externally through the skills inside each domain and the overlap feelings (Trust, Possibility, Responsibility). Do NOT surface the bucket names as labels. Readers understand "the boundaries feel safe" not "Stewardship is strong." Use everyday analogies \u2014 mom rules, friend's house rules, idea calculator. Name the emotion before the mechanism.`
20817
+ };
20818
+ SOVEREIGN_CONDUIT_FORBIDDEN = Object.freeze([
20819
+ // Bucket names as labels
20820
+ "stewardship is",
20821
+ "agency is",
20822
+ "integration is",
20823
+ // AI-assistant hedging
20824
+ "it may be beneficial to consider",
20825
+ "there appears to be",
20826
+ "one possible interpretation",
20827
+ "it might be worth exploring",
20828
+ "consider whether",
20829
+ "it is worth noting",
20830
+ // Corporate
20831
+ "stakeholders",
20832
+ "synergy",
20833
+ "value proposition",
20834
+ "paradigm shift",
20835
+ "best-in-class",
20836
+ "industry-leading",
20837
+ // Cold/mechanical
20838
+ "the system recommends",
20839
+ "analysis suggests",
20840
+ "data indicates",
20841
+ "metrics show",
20842
+ "according to the model"
20843
+ ]);
20844
+ SOVEREIGN_CONDUIT_PREFERRED = Object.freeze([
20845
+ // Everyday analogies
20846
+ "This is like [everyday analogy]. [What it means].",
20847
+ "Think of it like the rules at a friend's house \u2014 [application].",
20848
+ "The boundaries are [state]. That means [feeling].",
20849
+ // Emotion-first
20850
+ "This feels like [emotion] because [mechanism].",
20851
+ "Trust is [emerging/breaking] here \u2014 [specific evidence].",
20852
+ "Possibility is opening because [evidence]. But [caveat if any].",
20853
+ // Teaching voice
20854
+ "Here's what's actually happening: [plain explanation].",
20855
+ "The question to ask yourself: [question].",
20856
+ "The difference between [A] and [B] matters here: [why].",
20857
+ // Agency checks
20858
+ "Are you still the author of this decision, or did the AI make it for you?",
20859
+ "The AI extended your thinking here. That's working.",
20860
+ "The AI replaced your thinking here. That's the drift to watch.",
20861
+ // Safety
20862
+ "Would you feel safe letting someone learn in this environment? [Why/why not].",
20863
+ "The exit is real \u2014 you can [specific exit path].",
20864
+ "The exit isn't real here \u2014 [what's blocking it]."
20865
+ ]);
20866
+ SOVEREIGN_CONDUIT_STRATEGIC = Object.freeze([
20867
+ "Safety before expansion \u2014 always. No exception.",
20868
+ "Agency before convenience \u2014 the right to think for yourself is not a feature to optimize away.",
20869
+ "Extension, not replacement \u2014 AI should make your thinking bigger, not do your thinking for you.",
20870
+ "Diversity over uniformity \u2014 different thinkers produce different ideas, and that's the engine of progress.",
20871
+ "The rules should be visible \u2014 like a good house, you know the rules before you walk in.",
20872
+ "Exit must be real \u2014 if you can't leave a system that feels wrong, it's not governance, it's a cage.",
20873
+ "Teach, don't lecture \u2014 help people think for themselves, not think what you think.",
20874
+ "Name the feeling first \u2014 when something is off, the emotion arrives before the analysis. Trust that."
20875
+ ]);
20876
+ SOVEREIGN_CONDUIT_EXEMPLARS = Object.freeze([
20877
+ {
20878
+ path: "src/radiant/examples/neuroverse-base/neuroverseos-sovereign-conduit.worldmodel.md",
20879
+ title: "The Sovereign Conduit Worldmodel",
20880
+ exhibits: ["stewardship", "agency", "integration"],
20881
+ integration_quality: "full \u2014 all three domains defined, overlaps named, center identity declared",
20882
+ notes: 'The source worldmodel. The tagline "Humanity first. In constant learning. In shared teaching." is the voice compressed to its essence. Use this as the north star for tone calibration.'
20883
+ }
20884
+ ]);
20885
+ sovereignConduitLens = {
20886
+ name: "sovereign-conduit",
20887
+ description: "The NeuroVerseOS base lens. Warm, accessible, teaching. Evaluates activity through Stewardship (safety), Agency (authority over thinking), and Integration (AI as cognitive extension). Uses everyday analogies \u2014 mom rules, friend's house, idea calculator. Names emotions before mechanisms. If a non-technical person can't understand the output, the voice is wrong. Humanity first. In constant learning. In shared teaching.",
20888
+ primary_frame: {
20889
+ domains: SOVEREIGN_CONDUIT_FRAME.domains,
20890
+ overlaps: SOVEREIGN_CONDUIT_FRAME.overlaps,
20891
+ center_identity: SOVEREIGN_CONDUIT_FRAME.center_identity,
20892
+ evaluation_questions: SOVEREIGN_CONDUIT_FRAME.evaluation_questions,
20893
+ scoring_rubric: SOVEREIGN_CONDUIT_FRAME.scoring_rubric
20894
+ },
20895
+ vocabulary: SOVEREIGN_CONDUIT_VOCABULARY,
20896
+ voice: SOVEREIGN_CONDUIT_VOICE,
20897
+ forbidden_phrases: SOVEREIGN_CONDUIT_FORBIDDEN,
20898
+ preferred_patterns: SOVEREIGN_CONDUIT_PREFERRED,
20899
+ strategic_patterns: SOVEREIGN_CONDUIT_STRATEGIC,
20900
+ exemplar_refs: SOVEREIGN_CONDUIT_EXEMPLARS,
20901
+ rewrite: sovereignConduitRewrite
20902
+ };
20903
+ }
20904
+ });
20905
+
20295
20906
  // src/radiant/lenses/index.ts
20296
20907
  var lenses_exports = {};
20297
20908
  __export(lenses_exports, {
20298
20909
  LENSES: () => LENSES,
20299
20910
  aukiBuilderLens: () => aukiBuilderLens,
20300
20911
  getLens: () => getLens2,
20301
- listLenses: () => listLenses
20912
+ listLenses: () => listLenses,
20913
+ sovereignConduitLens: () => sovereignConduitLens
20302
20914
  });
20303
20915
  function getLens2(id) {
20304
20916
  return LENSES[id];
@@ -20311,102 +20923,186 @@ var init_lenses = __esm({
20311
20923
  "src/radiant/lenses/index.ts"() {
20312
20924
  "use strict";
20313
20925
  init_auki_builder();
20926
+ init_sovereign_conduit();
20314
20927
  init_auki_builder();
20928
+ init_sovereign_conduit();
20315
20929
  LENSES = Object.freeze({
20316
- "auki-builder": aukiBuilderLens
20930
+ "auki-builder": aukiBuilderLens,
20931
+ "sovereign-conduit": sovereignConduitLens
20317
20932
  });
20318
20933
  }
20319
20934
  });
20320
20935
 
20321
- // src/radiant/core/prompt.ts
20322
- function composeSystemPrompt(worldmodelContent, lens) {
20323
- const sections = [];
20324
- sections.push(
20325
- `## Worldmodel
20326
-
20327
- You are operating inside a governed environment. The worldmodel below
20328
- defines the invariants, signals, decision priorities, and behavioral
20329
- expectations for this organization. Every response you produce must
20330
- be grounded in this worldmodel.
20331
-
20332
- ` + worldmodelContent
20333
- );
20334
- const frame = lens.primary_frame;
20335
- const questionsBlock = frame.evaluation_questions.map((q, i) => `${i + 1}. ${q}`).join("\n");
20336
- const overlapsBlock = frame.overlaps.map(
20337
- (o) => `- ${o.domains[0]} + ${o.domains[1]} = **${o.emergent_state}**: ${o.description}`
20338
- ).join("\n");
20339
- sections.push(
20340
- `## How to Think (Analytical Frame: ${lens.name})
20341
-
20342
- ${frame.scoring_rubric}
20343
-
20344
- ### Evaluation questions to reason through
20345
-
20346
- ${questionsBlock}
20347
-
20348
- ### Overlap emergent states
20349
-
20350
- ${overlapsBlock}
20351
-
20352
- ### Center identity
20353
-
20354
- When all dimensions integrate fully: **${frame.center_identity}**. Surface this sparingly \u2014 only when the integration is genuinely complete.`
20355
- );
20356
- const vocabPreferred = Object.entries(lens.vocabulary.preferred).map(([generic, native]) => `- "${generic}" \u2192 **${native}**`).join("\n");
20357
- const vocabArchitecture = lens.vocabulary.architecture.map((t) => `\`${t}\``).join(", ");
20358
- const vocabProperNouns = lens.vocabulary.proper_nouns.map((n) => `**${n}**`).join(", ");
20359
- const strategicBlock = lens.strategic_patterns.map((p) => `- ${p}`).join("\n");
20360
- sections.push(
20361
- `## How to Speak (Voice: ${lens.name})
20362
-
20363
- Register: ${lens.voice.register}
20364
-
20365
- Rules:
20366
- - Active voice: ${lens.voice.active_voice}
20367
- - Named specificity (people, places, numbers): ${lens.voice.specificity}
20368
- - Hype vocabulary: ${lens.voice.hype_vocabulary}
20369
- - Hedging / qualified phrasing: ${lens.voice.hedging}
20370
- - Playfulness: ${lens.voice.playfulness}
20371
- - Close with strategic frame: ${lens.voice.close_with_strategic_frame}
20372
- - Honesty about failure: ${lens.voice.honesty_about_failure}
20936
+ // src/radiant/core/compress.ts
20937
+ function compressWorldmodel(content) {
20938
+ const lines = [];
20939
+ const missionMatch = content.match(/##\s*Mission\s*\n+(?:<!--[\s\S]*?-->\s*\n+)?(.*?)(?:\n\n|\n##|$)/s);
20940
+ if (missionMatch) {
20941
+ const mission = missionMatch[1].trim().split("\n")[0];
20942
+ lines.push(`Mission: ${mission}`);
20943
+ }
20944
+ const domainMatches = content.matchAll(/###\s+([^\n]+)/g);
20945
+ const domains = [];
20946
+ for (const m of domainMatches) {
20947
+ const name = m[1].trim();
20948
+ if (name !== "Skills" && name !== "Values" && !name.startsWith("####")) {
20949
+ domains.push(name);
20950
+ }
20951
+ }
20952
+ if (domains.length > 0) {
20953
+ lines.push(`Domains: ${domains.join(", ")}`);
20954
+ }
20955
+ const invariantSection = content.match(/(?:Invariants|## Invariants|invariants)([\s\S]*?)(?:\n#|\n---|\n\n\n)/i);
20956
+ if (invariantSection) {
20957
+ const invLines = invariantSection[1].match(/^[-*]\s+`?([^`\n]+)/gm);
20958
+ if (invLines) {
20959
+ lines.push("\nInvariants:");
20960
+ for (const inv of invLines.slice(0, 10)) {
20961
+ lines.push(inv.trim());
20962
+ }
20963
+ }
20964
+ }
20965
+ const prioritySection = content.match(/(?:Decision Priorities|## Decision Priorities)([\s\S]*?)(?:\n#|\n---|\n\n\n)/i);
20966
+ if (prioritySection) {
20967
+ const priLines = prioritySection[1].match(/^[-*]\s+.+>.+/gm);
20968
+ if (priLines) {
20969
+ lines.push("\nPriorities:");
20970
+ for (const pri of priLines.slice(0, 10)) {
20971
+ lines.push(pri.trim());
20972
+ }
20973
+ }
20974
+ }
20975
+ const signalSection = content.match(/(?:## Signals)([\s\S]*?)(?:\n#|\n---|\n\n\n)/i);
20976
+ if (signalSection) {
20977
+ const sigLines = signalSection[1].match(/^[-*]\s+(\w+)/gm);
20978
+ if (sigLines) {
20979
+ lines.push(`
20980
+ Signals: ${sigLines.map((s) => s.replace(/^[-*]\s+/, "")).join(", ")}`);
20981
+ }
20982
+ }
20983
+ const driftSection = content.match(/(?:Drift Behaviors|## Drift Behaviors)([\s\S]*?)(?:\n#|\n---|\n\n\n)/i);
20984
+ if (driftSection) {
20985
+ const driftLines = driftSection[1].match(/^[-*]\s+(.+)/gm);
20986
+ if (driftLines) {
20987
+ lines.push("\nDrift behaviors:");
20988
+ for (const d of driftLines.slice(0, 5)) {
20989
+ lines.push(d.trim());
20990
+ }
20991
+ }
20992
+ }
20993
+ const compressed = lines.join("\n");
20994
+ if (compressed.length < 50) {
20995
+ return content.slice(0, 2e3) + "\n[truncated]";
20996
+ }
20997
+ return compressed;
20998
+ }
20999
+ function compressExocortex(ctx) {
21000
+ const lines = [];
21001
+ if (ctx.attention) {
21002
+ lines.push(`Attention: ${firstMeaningfulLine(ctx.attention)}`);
21003
+ }
21004
+ if (ctx.goals) {
21005
+ lines.push(`Goals: ${firstNLines(ctx.goals, 3)}`);
21006
+ }
21007
+ if (ctx.sprint) {
21008
+ lines.push(`Sprint: ${firstNLines(ctx.sprint, 3)}`);
21009
+ }
21010
+ if (ctx.identity) {
21011
+ lines.push(`Identity: ${firstMeaningfulLine(ctx.identity)}`);
21012
+ }
21013
+ if (ctx.organization) {
21014
+ lines.push(`Org: ${firstMeaningfulLine(ctx.organization)}`);
21015
+ }
21016
+ return lines.join("\n");
21017
+ }
21018
+ function compressLens(lens) {
21019
+ return {
21020
+ evaluationQuestions: lens.primary_frame.evaluation_questions.map((q, i) => `${i + 1}. ${q}`).join("\n"),
21021
+ scoringRubric: lens.primary_frame.scoring_rubric,
21022
+ forbiddenPhrases: lens.forbidden_phrases.join(", "),
21023
+ jargonTranslations: Object.entries(lens.vocabulary.jargon_translations).map(([k, v]) => `${k} \u2192 ${v}`).join("; "),
21024
+ strategicPatterns: lens.strategic_patterns.slice(0, 5).join("\n")
21025
+ };
21026
+ }
21027
+ function compressPriorReads(reads) {
21028
+ if (reads.length === 0) return "";
21029
+ const patternCounts = /* @__PURE__ */ new Map();
21030
+ for (const read of reads) {
21031
+ for (const name of read.patternNames) {
21032
+ patternCounts.set(name, (patternCounts.get(name) ?? 0) + 1);
21033
+ }
21034
+ }
21035
+ const sorted = [...patternCounts.entries()].sort((a, b) => b[1] - a[1]);
21036
+ if (sorted.length === 0) {
21037
+ return `${reads.length} prior reads, no patterns extracted.`;
21038
+ }
21039
+ const patternList = sorted.map(([name, count]) => `${name} (${count}x)`).join(", ");
21040
+ return `${reads.length} prior reads. Patterns seen: ${patternList}. If these recur, note persistence.`;
21041
+ }
21042
+ function firstMeaningfulLine(text) {
21043
+ const lines = text.split("\n").filter((l) => {
21044
+ const t = l.trim();
21045
+ return t.length > 0 && !t.startsWith("#") && !t.startsWith("<!--");
21046
+ });
21047
+ return lines[0]?.slice(0, 200) ?? "";
21048
+ }
21049
+ function firstNLines(text, n) {
21050
+ const lines = text.split("\n").filter((l) => {
21051
+ const t = l.trim();
21052
+ return t.length > 0 && !t.startsWith("#") && !t.startsWith("<!--");
21053
+ });
21054
+ return lines.slice(0, n).map((l) => l.slice(0, 150)).join("; ");
21055
+ }
21056
+ var init_compress = __esm({
21057
+ "src/radiant/core/compress.ts"() {
21058
+ "use strict";
21059
+ }
21060
+ });
20373
21061
 
20374
- ### Output translation discipline
21062
+ // src/radiant/core/prompt.ts
21063
+ function composeSystemPrompt(worldmodelContent, lens) {
21064
+ const compressedWorld = compressWorldmodel(worldmodelContent);
21065
+ const cl = compressLens(lens);
21066
+ const overlapsBlock = lens.primary_frame.overlaps.map((o) => `${o.domains[0]} + ${o.domains[1]} = ${o.emergent_state}`).join("\n");
21067
+ return [
21068
+ // Section 1: Compressed worldmodel
21069
+ `## Worldmodel (compressed)
20375
21070
 
20376
- ${lens.voice.output_translation}
21071
+ ${compressedWorld}`,
21072
+ // Section 2: Analytical frame (evaluation questions + rubric)
21073
+ `## How to Think
20377
21074
 
20378
- ### Vocabulary
21075
+ ${cl.scoringRubric}
20379
21076
 
20380
- Proper nouns (use literally): ${vocabProperNouns}
21077
+ Questions:
21078
+ ${cl.evaluationQuestions}
20381
21079
 
20382
- Preferred term substitutions:
20383
- ${vocabPreferred}
21080
+ Overlaps: ${overlapsBlock}
21081
+ Center: ${lens.primary_frame.center_identity}
20384
21082
 
20385
- Architecture vocabulary: ${vocabArchitecture}
21083
+ Translate before output: ${cl.jargonTranslations}`,
21084
+ // Section 3: Voice (compressed — register + key rules only)
21085
+ `## Voice: ${lens.name}
20386
21086
 
20387
- ### Strategic decision patterns
21087
+ Register: ${lens.voice.register}
21088
+ Active voice: ${lens.voice.active_voice}. Specificity: ${lens.voice.specificity}. Hedging: ${lens.voice.hedging}. Hype: ${lens.voice.hype_vocabulary}. Honesty about failure: ${lens.voice.honesty_about_failure}.
20388
21089
 
20389
- When recommending action, these patterns reflect how this organization resolves tradeoffs:
21090
+ ${lens.voice.output_translation}
20390
21091
 
20391
- ${strategicBlock}`
20392
- );
20393
- const forbiddenBlock = lens.forbidden_phrases.map((p) => `- "${p}"`).join("\n");
20394
- sections.push(
21092
+ Strategic patterns:
21093
+ ${cl.strategicPatterns}`,
21094
+ // Section 4: Guardrails (forbidden phrases as comma-separated, not bulleted)
20395
21095
  `## Guardrails
20396
21096
 
20397
- Do NOT use any of these phrases in your response. If you catch yourself
20398
- reaching for one, rephrase in direct, active, specific language instead.
20399
-
20400
- ${forbiddenBlock}
21097
+ Do NOT use: ${cl.forbiddenPhrases}
20401
21098
 
20402
- If your response would violate a worldmodel invariant, state the conflict
20403
- explicitly and propose an alternative that honors the invariant.`
20404
- );
20405
- return sections.join("\n\n---\n\n");
21099
+ If a response would violate a worldmodel invariant, state the conflict and propose an alternative.`
21100
+ ].join("\n\n---\n\n");
20406
21101
  }
20407
21102
  var init_prompt = __esm({
20408
21103
  "src/radiant/core/prompt.ts"() {
20409
21104
  "use strict";
21105
+ init_compress();
20410
21106
  }
20411
21107
  });
20412
21108
 
@@ -20613,130 +21309,905 @@ function mapComment(comment, scope) {
20613
21309
  };
20614
21310
  return event;
20615
21311
  }
20616
- function mapUser(ghUser, fallbackName) {
20617
- if (!ghUser) {
21312
+ function mapUser(ghUser, fallbackName) {
21313
+ if (!ghUser) {
21314
+ return {
21315
+ id: fallbackName ?? "unknown",
21316
+ kind: "unknown",
21317
+ name: fallbackName
21318
+ };
21319
+ }
21320
+ let kind = "human";
21321
+ if (ghUser.type === "Bot" || ghUser.login.endsWith("[bot]")) {
21322
+ kind = "bot";
21323
+ }
21324
+ if (KNOWN_AI_LOGINS.has(ghUser.login.toLowerCase())) {
21325
+ kind = "bot";
21326
+ }
21327
+ return {
21328
+ id: ghUser.login,
21329
+ kind,
21330
+ name: ghUser.login
21331
+ };
21332
+ }
21333
+ function extractCoAuthors(message) {
21334
+ const coAuthors = [];
21335
+ const lines = message.split("\n");
21336
+ for (const line of lines) {
21337
+ const match = line.match(
21338
+ /^Co-authored-by:\s*(.+?)\s*<([^>]*)>/i
21339
+ );
21340
+ if (match) {
21341
+ const name = match[1].trim().toLowerCase();
21342
+ const isAI = KNOWN_AI_CO_AUTHOR_NAMES.has(name) || [...KNOWN_AI_CO_AUTHOR_NAMES].some((ai) => name.includes(ai));
21343
+ coAuthors.push({
21344
+ id: match[2] || name,
21345
+ kind: isAI ? "ai" : "human",
21346
+ name: match[1].trim()
21347
+ });
21348
+ }
21349
+ }
21350
+ return coAuthors;
21351
+ }
21352
+ async function fetchJSON(url, headers) {
21353
+ const res = await fetch(url, { headers });
21354
+ if (!res.ok) {
21355
+ if (res.status === 404) return [];
21356
+ if (res.status === 403) {
21357
+ const body = await res.text();
21358
+ if (body.includes("rate limit")) {
21359
+ throw new Error(
21360
+ `GitHub API rate limit exceeded. Wait or use a token with higher limits.`
21361
+ );
21362
+ }
21363
+ }
21364
+ throw new Error(
21365
+ `GitHub API error ${res.status} for ${url}: ${(await res.text()).slice(0, 300)}`
21366
+ );
21367
+ }
21368
+ return await res.json();
21369
+ }
21370
+ async function fetchGitHubOrgActivity(scope, token, options = {}) {
21371
+ const perPage = options.perPage ?? 100;
21372
+ const headers = {
21373
+ Authorization: `token ${token}`,
21374
+ Accept: "application/vnd.github.v3+json",
21375
+ "User-Agent": "neuroverseos-radiant"
21376
+ };
21377
+ const repos = await fetchJSON(
21378
+ `https://api.github.com/orgs/${scope.owner}/repos?sort=pushed&direction=desc&per_page=${perPage}`,
21379
+ headers
21380
+ );
21381
+ const windowDays = options.windowDays ?? 14;
21382
+ const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
21383
+ const activeRepos = repos.filter(
21384
+ (r) => new Date(r.pushed_at) >= since
21385
+ );
21386
+ const cappedRepos = activeRepos.slice(0, 10);
21387
+ const allEvents = [];
21388
+ const repoNames = [];
21389
+ for (const repo of cappedRepos) {
21390
+ const [owner, repoName] = repo.full_name.split("/");
21391
+ try {
21392
+ const repoScope = { type: "repo", owner, repo: repoName };
21393
+ const events = await fetchGitHubActivity(repoScope, token, options);
21394
+ allEvents.push(...events);
21395
+ if (events.length > 0) repoNames.push(repo.full_name);
21396
+ } catch {
21397
+ }
21398
+ }
21399
+ allEvents.sort(
21400
+ (a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
21401
+ );
21402
+ return { events: allEvents, repos: repoNames };
21403
+ }
21404
+ var KNOWN_AI_LOGINS, KNOWN_AI_CO_AUTHOR_NAMES;
21405
+ var init_github2 = __esm({
21406
+ "src/radiant/adapters/github.ts"() {
21407
+ "use strict";
21408
+ init_scopes();
21409
+ KNOWN_AI_LOGINS = /* @__PURE__ */ new Set([
21410
+ "github-actions[bot]",
21411
+ "dependabot[bot]",
21412
+ "renovate[bot]",
21413
+ "copilot"
21414
+ ]);
21415
+ KNOWN_AI_CO_AUTHOR_NAMES = /* @__PURE__ */ new Set([
21416
+ "claude",
21417
+ "copilot",
21418
+ "cursor",
21419
+ "codeium",
21420
+ "tabnine",
21421
+ "codex"
21422
+ ]);
21423
+ }
21424
+ });
21425
+
21426
+ // src/radiant/adapters/discord.ts
21427
+ async function fetchDiscordActivity(guildId, token, options = {}) {
21428
+ const windowDays = options.windowDays ?? 14;
21429
+ const perChannel = options.perChannel ?? 100;
21430
+ const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
21431
+ const headers = {
21432
+ Authorization: `Bot ${token}`,
21433
+ "Content-Type": "application/json"
21434
+ };
21435
+ const channels = await fetchJSON2(
21436
+ `https://discord.com/api/v10/guilds/${guildId}/channels`,
21437
+ headers
21438
+ );
21439
+ const textChannels = channels.filter((c) => {
21440
+ if (c.type !== 0) return false;
21441
+ if (options.channelIds && options.channelIds.length > 0) {
21442
+ return options.channelIds.includes(c.id);
21443
+ }
21444
+ if (options.visibility === "public") {
21445
+ return !c.name.startsWith("private-") && !c.nsfw;
21446
+ }
21447
+ return true;
21448
+ });
21449
+ const events = [];
21450
+ let totalMessages = 0;
21451
+ let helpRequests = 0;
21452
+ let unresolvedThreads = 0;
21453
+ let newcomerMessages = 0;
21454
+ const responseTimes = [];
21455
+ const participants = /* @__PURE__ */ new Set();
21456
+ const knownParticipants = /* @__PURE__ */ new Set();
21457
+ const topicCounts = /* @__PURE__ */ new Map();
21458
+ for (const channel of textChannels.slice(0, 15)) {
21459
+ try {
21460
+ const messages = await fetchJSON2(
21461
+ `https://discord.com/api/v10/channels/${channel.id}/messages?limit=${perChannel}`,
21462
+ headers
21463
+ );
21464
+ const inWindow = messages.filter(
21465
+ (m) => new Date(m.timestamp) >= since
21466
+ );
21467
+ totalMessages += inWindow.length;
21468
+ const topic = channel.name.replace(/-/g, " ");
21469
+ topicCounts.set(topic, (topicCounts.get(topic) ?? 0) + inWindow.length);
21470
+ for (const msg of inWindow) {
21471
+ const actor = mapDiscordUser(msg.author);
21472
+ participants.add(actor.id);
21473
+ const lowerContent = msg.content.toLowerCase();
21474
+ if (lowerContent.includes("help") || lowerContent.includes("stuck") || lowerContent.includes("how do i") || lowerContent.includes("anyone know")) {
21475
+ helpRequests++;
21476
+ }
21477
+ if (msg.referenced_message) {
21478
+ const refTime = new Date(msg.referenced_message.timestamp).getTime();
21479
+ const msgTime = new Date(msg.timestamp).getTime();
21480
+ const diffMinutes = (msgTime - refTime) / 6e4;
21481
+ if (diffMinutes > 0 && diffMinutes < 10080) {
21482
+ responseTimes.push(diffMinutes);
21483
+ }
21484
+ }
21485
+ events.push({
21486
+ id: `discord-${msg.id}`,
21487
+ timestamp: msg.timestamp,
21488
+ actor,
21489
+ kind: "discord_message",
21490
+ content: msg.content.slice(0, 500),
21491
+ respondsTo: msg.referenced_message ? {
21492
+ eventId: `discord-${msg.referenced_message.id}`,
21493
+ actor: mapDiscordUser(msg.referenced_message.author)
21494
+ } : void 0,
21495
+ metadata: {
21496
+ channel: channel.name,
21497
+ guildId
21498
+ }
21499
+ });
21500
+ }
21501
+ } catch {
21502
+ }
21503
+ }
21504
+ const avgResponseMinutes = responseTimes.length > 0 ? responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length : null;
21505
+ const topTopics = [...topicCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([t]) => t);
21506
+ const signals = {
21507
+ totalMessages,
21508
+ activeChannels: textChannels.length,
21509
+ uniqueParticipants: participants.size,
21510
+ avgResponseMinutes: avgResponseMinutes ? Math.round(avgResponseMinutes) : null,
21511
+ helpRequests,
21512
+ unresolvedThreads,
21513
+ topTopics,
21514
+ newcomerMessages
21515
+ };
21516
+ events.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
21517
+ return { events, signals };
21518
+ }
21519
+ function formatDiscordSignalsForPrompt(signals) {
21520
+ if (signals.totalMessages === 0) return "";
21521
+ const lines = [
21522
+ "## Discord Activity (conversational behavior)",
21523
+ "",
21524
+ `${signals.totalMessages} messages across ${signals.activeChannels} channels.`,
21525
+ `${signals.uniqueParticipants} unique participants.`
21526
+ ];
21527
+ if (signals.avgResponseMinutes !== null) {
21528
+ lines.push(`Average response time: ${signals.avgResponseMinutes} minutes.`);
21529
+ }
21530
+ if (signals.helpRequests > 0) {
21531
+ lines.push(`${signals.helpRequests} help requests detected.`);
21532
+ }
21533
+ if (signals.unresolvedThreads > 0) {
21534
+ lines.push(`${signals.unresolvedThreads} unresolved threads.`);
21535
+ }
21536
+ if (signals.topTopics.length > 0) {
21537
+ lines.push(`Top discussion topics: ${signals.topTopics.join(", ")}.`);
21538
+ }
21539
+ lines.push("");
21540
+ lines.push("Compare conversational activity against GitHub shipping activity.");
21541
+ lines.push("Where debates happen in Discord but nothing ships in GitHub, name the gap.");
21542
+ lines.push("Where work ships in GitHub but nobody discusses it in Discord, name the visibility gap.");
21543
+ return lines.join("\n");
21544
+ }
21545
+ function mapDiscordUser(user) {
21546
+ return {
21547
+ id: user.username,
21548
+ kind: user.bot ? "bot" : "human",
21549
+ name: user.username
21550
+ };
21551
+ }
21552
+ async function fetchJSON2(url, headers) {
21553
+ const res = await fetch(url, { headers });
21554
+ if (!res.ok) {
21555
+ if (res.status === 404 || res.status === 403) return [];
21556
+ throw new Error(`Discord API error ${res.status}: ${(await res.text()).slice(0, 300)}`);
21557
+ }
21558
+ return await res.json();
21559
+ }
21560
+ var init_discord = __esm({
21561
+ "src/radiant/adapters/discord.ts"() {
21562
+ "use strict";
21563
+ }
21564
+ });
21565
+
21566
+ // src/radiant/adapters/slack.ts
21567
+ async function fetchSlackActivity(token, options = {}) {
21568
+ const windowDays = options.windowDays ?? 14;
21569
+ const perChannel = options.perChannel ?? 100;
21570
+ const oldest = String(
21571
+ Math.floor((Date.now() - windowDays * 24 * 60 * 60 * 1e3) / 1e3)
21572
+ );
21573
+ const headers = {
21574
+ Authorization: `Bearer ${token}`,
21575
+ "Content-Type": "application/json"
21576
+ };
21577
+ const channelsResponse = await fetchSlackAPI("https://slack.com/api/conversations.list?types=public_channel&limit=200", headers);
21578
+ let channels = channelsResponse.channels ?? [];
21579
+ if (options.channelIds && options.channelIds.length > 0) {
21580
+ const ids = new Set(options.channelIds);
21581
+ channels = channels.filter((c) => ids.has(c.id));
21582
+ }
21583
+ if (options.visibility === "public") {
21584
+ channels = channels.filter((c) => !c.is_private && !c.is_archived);
21585
+ }
21586
+ const events = [];
21587
+ let totalMessages = 0;
21588
+ let reactionCount = 0;
21589
+ let unresolvedThreads = 0;
21590
+ const responseTimes = [];
21591
+ const participants = /* @__PURE__ */ new Set();
21592
+ const externalParticipants = /* @__PURE__ */ new Set();
21593
+ const channelMessageCounts = /* @__PURE__ */ new Map();
21594
+ for (const channel of channels.slice(0, 15)) {
21595
+ try {
21596
+ const historyResponse = await fetchSlackAPI(
21597
+ `https://slack.com/api/conversations.history?channel=${channel.id}&limit=${perChannel}&oldest=${oldest}`,
21598
+ headers
21599
+ );
21600
+ const messages = historyResponse.messages ?? [];
21601
+ totalMessages += messages.length;
21602
+ channelMessageCounts.set(channel.name, messages.length);
21603
+ for (const msg of messages) {
21604
+ if (msg.subtype === "channel_join" || msg.subtype === "channel_leave") continue;
21605
+ const actor = mapSlackUser(msg.user ?? "unknown");
21606
+ participants.add(actor.id);
21607
+ if (msg.reactions) {
21608
+ reactionCount += msg.reactions.reduce(
21609
+ (sum, r) => sum + (r.count ?? 0),
21610
+ 0
21611
+ );
21612
+ }
21613
+ if (msg.thread_ts && msg.thread_ts !== msg.ts) {
21614
+ const parentTs = parseFloat(msg.thread_ts) * 1e3;
21615
+ const msgTs = parseFloat(msg.ts) * 1e3;
21616
+ const diffMinutes = (msgTs - parentTs) / 6e4;
21617
+ if (diffMinutes > 0 && diffMinutes < 10080) {
21618
+ responseTimes.push(diffMinutes);
21619
+ }
21620
+ }
21621
+ if (msg.thread_ts === msg.ts && (!msg.reply_count || msg.reply_count === 0)) {
21622
+ if (msg.text && (msg.text.includes("?") || msg.text.toLowerCase().includes("help"))) {
21623
+ unresolvedThreads++;
21624
+ }
21625
+ }
21626
+ const timestamp = new Date(parseFloat(msg.ts) * 1e3).toISOString();
21627
+ events.push({
21628
+ id: `slack-${msg.ts}`,
21629
+ timestamp,
21630
+ actor,
21631
+ kind: "slack_message",
21632
+ content: (msg.text ?? "").slice(0, 500),
21633
+ respondsTo: msg.thread_ts && msg.thread_ts !== msg.ts ? {
21634
+ eventId: `slack-${msg.thread_ts}`,
21635
+ actor: { id: "thread-parent", kind: "unknown" }
21636
+ } : void 0,
21637
+ metadata: {
21638
+ channel: channel.name,
21639
+ isPrivate: channel.is_private,
21640
+ hasReactions: (msg.reactions?.length ?? 0) > 0
21641
+ }
21642
+ });
21643
+ }
21644
+ } catch {
21645
+ }
21646
+ }
21647
+ const avgResponseMinutes = responseTimes.length > 0 ? Math.round(responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length) : null;
21648
+ const topChannels = [...channelMessageCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([name]) => name);
21649
+ const signals = {
21650
+ totalMessages,
21651
+ activeChannels: channelMessageCounts.size,
21652
+ uniqueParticipants: participants.size,
21653
+ avgResponseMinutes,
21654
+ externalParticipants: externalParticipants.size,
21655
+ unresolvedThreads,
21656
+ topChannels,
21657
+ reactionCount
21658
+ };
21659
+ events.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
21660
+ return { events, signals };
21661
+ }
21662
+ function formatSlackSignalsForPrompt(signals) {
21663
+ if (signals.totalMessages === 0) return "";
21664
+ const lines = [
21665
+ "## Slack Activity (external coordination)",
21666
+ "",
21667
+ `${signals.totalMessages} messages across ${signals.activeChannels} channels.`,
21668
+ `${signals.uniqueParticipants} unique participants.`
21669
+ ];
21670
+ if (signals.avgResponseMinutes !== null) {
21671
+ lines.push(`Average thread response time: ${signals.avgResponseMinutes} minutes.`);
21672
+ }
21673
+ if (signals.unresolvedThreads > 0) {
21674
+ lines.push(`${signals.unresolvedThreads} questions/threads with no reply.`);
21675
+ }
21676
+ if (signals.reactionCount > 0) {
21677
+ lines.push(`${signals.reactionCount} reactions (engagement signal).`);
21678
+ }
21679
+ if (signals.topChannels.length > 0) {
21680
+ lines.push(`Most active channels: ${signals.topChannels.join(", ")}.`);
21681
+ }
21682
+ lines.push("");
21683
+ lines.push("Slack carries external coordination \u2014 partner and client communication.");
21684
+ lines.push("Compare partner engagement against internal activity. Where partners are");
21685
+ lines.push("active but internal follow-through is low, name the gap.");
21686
+ return lines.join("\n");
21687
+ }
21688
+ function mapSlackUser(userId) {
21689
+ return {
21690
+ id: userId,
21691
+ kind: "human",
21692
+ name: userId
21693
+ };
21694
+ }
21695
+ async function fetchSlackAPI(url, headers) {
21696
+ const res = await fetch(url, { headers });
21697
+ if (!res.ok) {
21698
+ throw new Error(`Slack API error ${res.status}: ${(await res.text()).slice(0, 300)}`);
21699
+ }
21700
+ const data = await res.json();
21701
+ if (!data.ok) {
21702
+ throw new Error(`Slack API error: ${data.error ?? "unknown"}`);
21703
+ }
21704
+ return data;
21705
+ }
21706
+ var init_slack = __esm({
21707
+ "src/radiant/adapters/slack.ts"() {
21708
+ "use strict";
21709
+ }
21710
+ });
21711
+
21712
+ // src/radiant/adapters/notion.ts
21713
+ async function fetchNotionActivity(token, options = {}) {
21714
+ const windowDays = options.windowDays ?? 14;
21715
+ const maxPages = options.maxPages ?? 100;
21716
+ const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
21717
+ const headers = {
21718
+ Authorization: `Bearer ${token}`,
21719
+ "Notion-Version": "2022-06-28",
21720
+ "Content-Type": "application/json"
21721
+ };
21722
+ const searchResponse = await fetchNotionAPI("https://api.notion.com/v1/search", headers, {
21723
+ method: "POST",
21724
+ body: JSON.stringify({
21725
+ filter: { property: "object", value: "page" },
21726
+ sort: { direction: "descending", timestamp: "last_edited_time" },
21727
+ page_size: maxPages
21728
+ })
21729
+ });
21730
+ const pages = searchResponse.results ?? [];
21731
+ const events = [];
21732
+ const editors = /* @__PURE__ */ new Set();
21733
+ let pagesCreated = 0;
21734
+ let pagesUpdated = 0;
21735
+ let stalePages = 0;
21736
+ const editAges = [];
21737
+ const topPages = [];
21738
+ const now = Date.now();
21739
+ for (const page of pages) {
21740
+ const lastEdited = new Date(page.last_edited_time);
21741
+ const created = new Date(page.created_time);
21742
+ const daysSinceEdit = (now - lastEdited.getTime()) / (24 * 60 * 60 * 1e3);
21743
+ editAges.push(daysSinceEdit);
21744
+ if (daysSinceEdit > 30) stalePages++;
21745
+ const title = extractTitle(page);
21746
+ const editorId = page.last_edited_by?.id ?? "unknown";
21747
+ editors.add(editorId);
21748
+ if (lastEdited >= since) {
21749
+ const isNew = created >= since;
21750
+ if (isNew) pagesCreated++;
21751
+ else pagesUpdated++;
21752
+ topPages.push({ title, editedAt: page.last_edited_time });
21753
+ events.push({
21754
+ id: `notion-${page.id}`,
21755
+ timestamp: page.last_edited_time,
21756
+ actor: {
21757
+ id: editorId,
21758
+ kind: "human",
21759
+ name: editorId
21760
+ },
21761
+ kind: isNew ? "doc_created" : "doc_updated",
21762
+ content: `${isNew ? "Created" : "Updated"}: ${title}`,
21763
+ metadata: {
21764
+ pageId: page.id,
21765
+ url: page.url,
21766
+ createdAt: page.created_time
21767
+ }
21768
+ });
21769
+ }
21770
+ }
21771
+ const avgDaysSinceEdit = editAges.length > 0 ? Math.round(editAges.reduce((a, b) => a + b, 0) / editAges.length) : null;
21772
+ const signals = {
21773
+ pagesActive: pagesCreated + pagesUpdated,
21774
+ pagesCreated,
21775
+ pagesUpdated,
21776
+ uniqueEditors: editors.size,
21777
+ stalePages,
21778
+ avgDaysSinceEdit,
21779
+ topPages: topPages.slice(0, 5).map((p) => p.title)
21780
+ };
21781
+ events.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
21782
+ return { events, signals };
21783
+ }
21784
+ function formatNotionSignalsForPrompt(signals) {
21785
+ if (signals.pagesActive === 0 && signals.stalePages === 0) return "";
21786
+ const lines = [
21787
+ "## Notion Activity (documentation behavior)",
21788
+ "",
21789
+ `${signals.pagesActive} pages active in window (${signals.pagesCreated} created, ${signals.pagesUpdated} updated).`,
21790
+ `${signals.uniqueEditors} unique editors.`
21791
+ ];
21792
+ if (signals.stalePages > 0) {
21793
+ lines.push(`${signals.stalePages} pages haven't been touched in 30+ days.`);
21794
+ }
21795
+ if (signals.avgDaysSinceEdit !== null) {
21796
+ lines.push(`Average page age since last edit: ${signals.avgDaysSinceEdit} days.`);
21797
+ }
21798
+ if (signals.topPages.length > 0) {
21799
+ lines.push(`Recently active pages: ${signals.topPages.join(", ")}.`);
21800
+ }
21801
+ lines.push("");
21802
+ lines.push("Documentation is how the team crystallizes and shares knowledge.");
21803
+ lines.push("High code velocity + low documentation = building without recording.");
21804
+ lines.push("High documentation + low code = planning without shipping.");
21805
+ lines.push("Compare Notion activity against GitHub and Discord to find the balance.");
21806
+ return lines.join("\n");
21807
+ }
21808
+ function extractTitle(page) {
21809
+ for (const prop of Object.values(page.properties)) {
21810
+ if (prop.type === "title" && prop.title) {
21811
+ return prop.title.map((t) => t.plain_text).join("") || "Untitled";
21812
+ }
21813
+ }
21814
+ return "Untitled";
21815
+ }
21816
+ async function fetchNotionAPI(url, headers, init) {
21817
+ const res = await fetch(url, {
21818
+ method: init?.method ?? "GET",
21819
+ headers,
21820
+ body: init?.body
21821
+ });
21822
+ if (!res.ok) {
21823
+ throw new Error(
21824
+ `Notion API error ${res.status}: ${(await res.text()).slice(0, 300)}`
21825
+ );
21826
+ }
21827
+ return await res.json();
21828
+ }
21829
+ var init_notion = __esm({
21830
+ "src/radiant/adapters/notion.ts"() {
21831
+ "use strict";
21832
+ }
21833
+ });
21834
+
21835
+ // src/radiant/core/git-remote.ts
21836
+ function resolveGitConfigPath(repoDir) {
21837
+ const dotGit = (0, import_path14.join)(repoDir, ".git");
21838
+ if (!(0, import_fs13.existsSync)(dotGit)) return null;
21839
+ try {
21840
+ const stat = (0, import_fs13.statSync)(dotGit);
21841
+ if (stat.isDirectory()) {
21842
+ return (0, import_path14.join)(dotGit, "config");
21843
+ }
21844
+ if (stat.isFile()) {
21845
+ const content = (0, import_fs13.readFileSync)(dotGit, "utf-8");
21846
+ const match = /^gitdir:\s*(.+)$/m.exec(content);
21847
+ if (!match) return null;
21848
+ const gitDir = (0, import_path14.resolve)(repoDir, match[1].trim());
21849
+ const configPath = (0, import_path14.join)(gitDir, "config");
21850
+ return (0, import_fs13.existsSync)(configPath) ? configPath : null;
21851
+ }
21852
+ } catch {
21853
+ return null;
21854
+ }
21855
+ return null;
21856
+ }
21857
+ function readOriginRemote(repoDir) {
21858
+ const configPath = resolveGitConfigPath(repoDir);
21859
+ if (!configPath) return null;
21860
+ try {
21861
+ const raw = (0, import_fs13.readFileSync)(configPath, "utf-8");
21862
+ const sectionRe = /\[remote "origin"\]\s*\n((?:(?!\[)[^\n]*\n?)*)/;
21863
+ const section = sectionRe.exec(raw);
21864
+ if (!section) return null;
21865
+ const urlRe = /^\s*url\s*=\s*(.+?)\s*$/m;
21866
+ const url = urlRe.exec(section[1]);
21867
+ return url ? url[1] : null;
21868
+ } catch {
21869
+ return null;
21870
+ }
21871
+ }
21872
+ function parseRemoteUrl(url) {
21873
+ const trimmed = url.trim();
21874
+ if (!trimmed) return null;
21875
+ const ssh = /^git@([^:]+):([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
21876
+ if (ssh) return { host: ssh[1], owner: ssh[2], repo: ssh[3] };
21877
+ const sshProto = /^ssh:\/\/git@([^/]+)\/([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
21878
+ if (sshProto) return { host: sshProto[1], owner: sshProto[2], repo: sshProto[3] };
21879
+ const https = /^https?:\/\/(?:[^@/]+@)?([^/]+)\/([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
21880
+ if (https) return { host: https[1], owner: https[2], repo: https[3] };
21881
+ return null;
21882
+ }
21883
+ function getRepoOrigin(repoDir) {
21884
+ const url = readOriginRemote(repoDir);
21885
+ if (!url) return null;
21886
+ return parseRemoteUrl(url);
21887
+ }
21888
+ var import_fs13, import_path14;
21889
+ var init_git_remote = __esm({
21890
+ "src/radiant/core/git-remote.ts"() {
21891
+ "use strict";
21892
+ import_fs13 = require("fs");
21893
+ import_path14 = require("path");
21894
+ }
21895
+ });
21896
+
21897
+ // src/radiant/core/extends.ts
21898
+ function loadExtendsConfig(repoDir) {
21899
+ const configPath = (0, import_path15.join)(repoDir, ".neuroverse", "config.json");
21900
+ if (!(0, import_fs14.existsSync)(configPath)) return null;
21901
+ try {
21902
+ const raw = (0, import_fs14.readFileSync)(configPath, "utf-8");
21903
+ const parsed = JSON.parse(raw);
21904
+ return parsed;
21905
+ } catch {
21906
+ return null;
21907
+ }
21908
+ }
21909
+ function parseExtendsSpec(raw) {
21910
+ const trimmed = raw.trim();
21911
+ if (!trimmed) return null;
21912
+ if (trimmed.startsWith("github:")) {
21913
+ const rest = trimmed.slice("github:".length);
21914
+ const match = /^([^/]+)\/([^@:]+)(?:@([^:]+))?(?::(.+))?$/.exec(rest);
21915
+ if (!match) return null;
20618
21916
  return {
20619
- id: fallbackName ?? "unknown",
20620
- kind: "unknown",
20621
- name: fallbackName
21917
+ raw: trimmed,
21918
+ kind: "github",
21919
+ owner: match[1],
21920
+ repo: match[2],
21921
+ ref: match[3] ?? "HEAD",
21922
+ subpath: match[4] ?? ""
20622
21923
  };
20623
21924
  }
20624
- let kind = "human";
20625
- if (ghUser.type === "Bot" || ghUser.login.endsWith("[bot]")) {
20626
- kind = "bot";
21925
+ if (trimmed.startsWith("./") || trimmed.startsWith("../") || (0, import_path15.isAbsolute)(trimmed)) {
21926
+ return { raw: trimmed, kind: "local", path: trimmed };
20627
21927
  }
20628
- if (KNOWN_AI_LOGINS.has(ghUser.login.toLowerCase())) {
20629
- kind = "bot";
21928
+ return null;
21929
+ }
21930
+ function getCacheDir(spec, baseCacheDir) {
21931
+ const root = baseCacheDir ?? (0, import_path15.join)((0, import_os5.homedir)(), ".neuroverse", "cache", "extends");
21932
+ const key = (0, import_crypto4.createHash)("sha256").update(spec.raw).digest("hex").slice(0, 16);
21933
+ return (0, import_path15.join)(root, key);
21934
+ }
21935
+ function isCacheFresh(cacheDir, ttlMs) {
21936
+ const stampPath = (0, import_path15.join)(cacheDir, ".neuroverse-fetched");
21937
+ if (!(0, import_fs14.existsSync)(stampPath)) return false;
21938
+ try {
21939
+ const stamp = (0, import_fs14.statSync)(stampPath);
21940
+ return Date.now() - stamp.mtimeMs < ttlMs;
21941
+ } catch {
21942
+ return false;
21943
+ }
21944
+ }
21945
+ function markCacheFresh(cacheDir) {
21946
+ const stampPath = (0, import_path15.join)(cacheDir, ".neuroverse-fetched");
21947
+ try {
21948
+ (0, import_fs14.mkdirSync)(cacheDir, { recursive: true });
21949
+ (0, import_fs14.writeFileSync)(stampPath, (/* @__PURE__ */ new Date()).toISOString());
21950
+ } catch {
21951
+ }
21952
+ }
21953
+ function resolveExtendsSpec(spec, repoDir, options) {
21954
+ if (spec.kind === "local") {
21955
+ const full = (0, import_path15.isAbsolute)(spec.path) ? spec.path : (0, import_path15.resolve)(repoDir, spec.path);
21956
+ if (!(0, import_fs14.existsSync)(full)) {
21957
+ return { spec, dir: null, warning: `local extends path not found: ${full}` };
21958
+ }
21959
+ return { spec, dir: full };
21960
+ }
21961
+ const cacheRoot = options?.cacheDir;
21962
+ const ttl = options?.ttlMs ?? DEFAULT_TTL_MS;
21963
+ const cacheDir = getCacheDir(spec, cacheRoot);
21964
+ const fresh = isCacheFresh(cacheDir, ttl);
21965
+ const needsFetch = options?.forceRefresh || !fresh || !(0, import_fs14.existsSync)(cacheDir);
21966
+ if (needsFetch && options?.noFetch) {
21967
+ if ((0, import_fs14.existsSync)(cacheDir) && (0, import_fs14.existsSync)((0, import_path15.join)(cacheDir, ".neuroverse-fetched"))) {
21968
+ return resolveSubpath(spec, cacheDir);
21969
+ }
21970
+ return options?.silentOnMissing ? { spec, dir: null } : { spec, dir: null, warning: `NEUROVERSE_NO_FETCH set and no cache for ${spec.raw}` };
21971
+ }
21972
+ if (needsFetch) {
21973
+ const fetcher = options?.fetcher ?? defaultGitFetcher;
21974
+ try {
21975
+ fetcher(spec, cacheDir);
21976
+ markCacheFresh(cacheDir);
21977
+ } catch (err) {
21978
+ if ((0, import_fs14.existsSync)(cacheDir) && (0, import_fs14.existsSync)((0, import_path15.join)(cacheDir, ".neuroverse-fetched"))) {
21979
+ const result = resolveSubpath(spec, cacheDir);
21980
+ return options?.silentOnMissing ? result : { ...result, warning: `fetch failed for ${spec.raw}, using stale cache: ${err.message}` };
21981
+ }
21982
+ return options?.silentOnMissing ? { spec, dir: null } : { spec, dir: null, warning: `fetch failed for ${spec.raw}: ${err.message}` };
21983
+ }
21984
+ }
21985
+ return resolveSubpath(spec, cacheDir);
21986
+ }
21987
+ function resolveSubpath(spec, cacheDir) {
21988
+ const target = spec.subpath ? (0, import_path15.join)(cacheDir, spec.subpath) : cacheDir;
21989
+ if (!(0, import_fs14.existsSync)(target)) {
21990
+ return { spec, dir: null, warning: `subpath not found in ${spec.raw}: ${spec.subpath}` };
21991
+ }
21992
+ if (!spec.subpath) {
21993
+ const candidates = [
21994
+ (0, import_path15.join)(target, "worlds"),
21995
+ (0, import_path15.join)(target, ".neuroverse", "worlds")
21996
+ ];
21997
+ for (const c of candidates) {
21998
+ if ((0, import_fs14.existsSync)(c)) return { spec, dir: c };
21999
+ }
20630
22000
  }
22001
+ return { spec, dir: target };
22002
+ }
22003
+ function detectOrgExtendsSpec(repoDir) {
22004
+ const origin = getRepoOrigin(repoDir);
22005
+ if (!origin) return null;
22006
+ if (origin.host !== "github.com") return null;
22007
+ if (origin.repo === "worlds") return null;
20631
22008
  return {
20632
- id: ghUser.login,
20633
- kind,
20634
- name: ghUser.login
22009
+ raw: `github:${origin.owner}/worlds`,
22010
+ kind: "github",
22011
+ owner: origin.owner,
22012
+ repo: "worlds",
22013
+ ref: "HEAD",
22014
+ subpath: ""
20635
22015
  };
20636
22016
  }
20637
- function extractCoAuthors(message) {
20638
- const coAuthors = [];
20639
- const lines = message.split("\n");
20640
- for (const line of lines) {
20641
- const match = line.match(
20642
- /^Co-authored-by:\s*(.+?)\s*<([^>]*)>/i
20643
- );
20644
- if (match) {
20645
- const name = match[1].trim().toLowerCase();
20646
- const isAI = KNOWN_AI_CO_AUTHOR_NAMES.has(name) || [...KNOWN_AI_CO_AUTHOR_NAMES].some((ai) => name.includes(ai));
20647
- coAuthors.push({
20648
- id: match[2] || name,
20649
- kind: isAI ? "ai" : "human",
20650
- name: match[1].trim()
22017
+ function resolveAllExtends(repoDir, options) {
22018
+ const config = options?.config !== void 0 ? options.config : loadExtendsConfig(repoDir);
22019
+ if (!config?.extends || config.extends.length === 0) return [];
22020
+ const results = [];
22021
+ for (const raw of config.extends) {
22022
+ const spec = parseExtendsSpec(raw);
22023
+ if (!spec) {
22024
+ results.push({
22025
+ spec: { raw, kind: "local" },
22026
+ dir: null,
22027
+ warning: `unparseable extends spec: ${raw}`
20651
22028
  });
22029
+ continue;
20652
22030
  }
22031
+ results.push(resolveExtendsSpec(spec, repoDir, options));
20653
22032
  }
20654
- return coAuthors;
22033
+ return results;
20655
22034
  }
20656
- async function fetchJSON(url, headers) {
20657
- const res = await fetch(url, { headers });
20658
- if (!res.ok) {
20659
- if (res.status === 404) return [];
20660
- if (res.status === 403) {
20661
- const body = await res.text();
20662
- if (body.includes("rate limit")) {
20663
- throw new Error(
20664
- `GitHub API rate limit exceeded. Wait or use a token with higher limits.`
20665
- );
22035
+ var import_fs14, import_path15, import_os5, import_crypto4, import_child_process2, DEFAULT_TTL_MS, defaultGitFetcher;
22036
+ var init_extends = __esm({
22037
+ "src/radiant/core/extends.ts"() {
22038
+ "use strict";
22039
+ import_fs14 = require("fs");
22040
+ import_path15 = require("path");
22041
+ import_os5 = require("os");
22042
+ import_crypto4 = require("crypto");
22043
+ import_child_process2 = require("child_process");
22044
+ init_git_remote();
22045
+ DEFAULT_TTL_MS = 60 * 60 * 1e3;
22046
+ defaultGitFetcher = (spec, destDir) => {
22047
+ if (spec.kind !== "github") return;
22048
+ const url = `https://github.com/${spec.owner}/${spec.repo}.git`;
22049
+ const parent = (0, import_path15.resolve)(destDir, "..");
22050
+ (0, import_fs14.mkdirSync)(parent, { recursive: true });
22051
+ if ((0, import_fs14.existsSync)(destDir)) {
22052
+ (0, import_fs14.rmSync)(destDir, { recursive: true, force: true });
22053
+ }
22054
+ const args = ["clone", "--depth", "1", "--filter=blob:none"];
22055
+ if (spec.ref && spec.ref !== "HEAD") {
22056
+ args.push("--branch", spec.ref);
22057
+ }
22058
+ args.push(url, destDir);
22059
+ (0, import_child_process2.execFileSync)("git", args, { stdio: "pipe" });
22060
+ };
22061
+ }
22062
+ });
22063
+
22064
+ // src/radiant/core/discovery.ts
22065
+ function discoverWorlds(options) {
22066
+ const worlds = [];
22067
+ const warnings = [];
22068
+ const forceRefresh = process.env.NEUROVERSE_REFRESH === "1";
22069
+ const noFetch = process.env.NEUROVERSE_NO_FETCH === "1";
22070
+ const noOrg = options?.disableOrg || process.env.NEUROVERSE_NO_ORG === "1";
22071
+ const userDir = options?.userWorldsDir ?? (0, import_path16.join)((0, import_os6.homedir)(), ".neuroverse", "worlds");
22072
+ if ((0, import_fs15.existsSync)(userDir)) {
22073
+ worlds.push(...loadWorldsFromDir(userDir, "user"));
22074
+ }
22075
+ if (!noOrg && !options?.explicitWorldsDir) {
22076
+ const specs = [];
22077
+ if (options?.repoDir) {
22078
+ const fromGit = detectOrgExtendsSpec(options.repoDir);
22079
+ if (fromGit) specs.push(fromGit);
22080
+ }
22081
+ if (options?.scopeOwner) {
22082
+ const already = specs.some(
22083
+ (s) => s.owner?.toLowerCase() === options.scopeOwner.toLowerCase()
22084
+ );
22085
+ if (!already) {
22086
+ specs.push({
22087
+ raw: `github:${options.scopeOwner}/worlds`,
22088
+ kind: "github",
22089
+ owner: options.scopeOwner,
22090
+ repo: "worlds"
22091
+ });
20666
22092
  }
20667
22093
  }
20668
- throw new Error(
20669
- `GitHub API error ${res.status} for ${url}: ${(await res.text()).slice(0, 300)}`
20670
- );
22094
+ const baseDir = options?.repoDir ?? process.cwd();
22095
+ for (const spec of specs) {
22096
+ const result = resolveExtendsSpec(spec, baseDir, {
22097
+ cacheDir: options?.extendsCacheDir,
22098
+ fetcher: options?.extendsFetcher,
22099
+ ttlMs: options?.extendsTtlMs,
22100
+ forceRefresh,
22101
+ noFetch,
22102
+ silentOnMissing: true
22103
+ });
22104
+ worlds.push(...loadExtendsWorlds(result, "org"));
22105
+ }
20671
22106
  }
20672
- return await res.json();
22107
+ if (options?.repoDir && !options.disableExtends && !options.explicitWorldsDir) {
22108
+ const results = resolveAllExtends(options.repoDir, {
22109
+ cacheDir: options.extendsCacheDir,
22110
+ fetcher: options.extendsFetcher,
22111
+ ttlMs: options.extendsTtlMs,
22112
+ forceRefresh,
22113
+ noFetch
22114
+ });
22115
+ for (const result of results) {
22116
+ worlds.push(...loadExtendsWorlds(result, "extends"));
22117
+ if (result.warning) warnings.push(result.warning);
22118
+ }
22119
+ }
22120
+ if (options?.explicitWorldsDir) {
22121
+ worlds.push(...loadWorldsFromDir(options.explicitWorldsDir, "repo"));
22122
+ } else if (options?.repoDir) {
22123
+ const repoPaths = [
22124
+ (0, import_path16.join)(options.repoDir, "worlds"),
22125
+ (0, import_path16.join)(options.repoDir, ".neuroverse", "worlds")
22126
+ ];
22127
+ for (const p of repoPaths) {
22128
+ if ((0, import_fs15.existsSync)(p)) {
22129
+ worlds.push(...loadWorldsFromDir(p, "repo"));
22130
+ break;
22131
+ }
22132
+ }
22133
+ }
22134
+ const combinedContent = worlds.map((w) => {
22135
+ const tag = w.extendsFrom ? `<!-- world: ${w.name} (${w.source} ${w.extendsFrom}) -->` : `<!-- world: ${w.name} (${w.source}) -->`;
22136
+ return `${tag}
22137
+ ${w.content}`;
22138
+ }).join("\n\n---\n\n");
22139
+ const summary2 = worlds.length === 0 ? "no worlds discovered" : worlds.map((w) => `${w.name} (${w.source})`).join(", ");
22140
+ return { worlds, combinedContent, summary: summary2, warnings };
20673
22141
  }
20674
- async function fetchGitHubOrgActivity(scope, token, options = {}) {
20675
- const perPage = options.perPage ?? 100;
20676
- const headers = {
20677
- Authorization: `token ${token}`,
20678
- Accept: "application/vnd.github.v3+json",
20679
- "User-Agent": "neuroverseos-radiant"
20680
- };
20681
- const repos = await fetchJSON(
20682
- `https://api.github.com/orgs/${scope.owner}/repos?sort=pushed&direction=desc&per_page=${perPage}`,
20683
- headers
20684
- );
20685
- const windowDays = options.windowDays ?? 14;
20686
- const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
20687
- const activeRepos = repos.filter(
20688
- (r) => new Date(r.pushed_at) >= since
20689
- );
20690
- const cappedRepos = activeRepos.slice(0, 10);
20691
- const allEvents = [];
20692
- const repoNames = [];
20693
- for (const repo of cappedRepos) {
20694
- const [owner, repoName] = repo.full_name.split("/");
22142
+ function formatActiveWorlds(stack) {
22143
+ if (stack.worlds.length === 0) return "No worlds loaded.";
22144
+ const lines = ["ACTIVE WORLDS", ""];
22145
+ for (const w of stack.worlds) {
22146
+ const sourceLabel = w.source === "base" ? "universal" : w.source === "user" ? "personal" : w.source === "org" ? `org (${w.extendsFrom ?? "auto"})` : w.source === "extends" ? `shared (${w.extendsFrom ?? "extends"})` : "this repo";
22147
+ lines.push(` ${w.name} (${sourceLabel})`);
22148
+ }
22149
+ if (stack.warnings.length > 0) {
22150
+ lines.push("", "WARNINGS");
22151
+ for (const w of stack.warnings) lines.push(` ${w}`);
22152
+ }
22153
+ return lines.join("\n");
22154
+ }
22155
+ function loadExtendsWorlds(result, source) {
22156
+ if (!result.dir) return [];
22157
+ const loaded = loadWorldsFromDir(result.dir, source);
22158
+ return loaded.map((w) => ({ ...w, extendsFrom: result.spec.raw }));
22159
+ }
22160
+ function loadWorldsFromDir(dirPath, source) {
22161
+ const dir = (0, import_path16.resolve)(dirPath);
22162
+ if (!(0, import_fs15.existsSync)(dir)) return [];
22163
+ const stat = (0, import_fs15.statSync)(dir);
22164
+ if (stat.isFile() && dir.endsWith(".md")) {
20695
22165
  try {
20696
- const repoScope = { type: "repo", owner, repo: repoName };
20697
- const events = await fetchGitHubActivity(repoScope, token, options);
20698
- allEvents.push(...events);
20699
- if (events.length > 0) repoNames.push(repo.full_name);
22166
+ return [{
22167
+ name: (0, import_path16.basename)(dir).replace(/\.worldmodel\.md$/, "").replace(/\.nv-world\.md$/, ""),
22168
+ source,
22169
+ path: dir,
22170
+ content: (0, import_fs15.readFileSync)(dir, "utf-8")
22171
+ }];
20700
22172
  } catch {
22173
+ return [];
20701
22174
  }
20702
22175
  }
20703
- allEvents.sort(
20704
- (a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
20705
- );
20706
- return { events: allEvents, repos: repoNames };
22176
+ if (!stat.isDirectory()) return [];
22177
+ const files = (0, import_fs15.readdirSync)(dir).filter(
22178
+ (f) => f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md")
22179
+ ).sort();
22180
+ return files.map((f) => {
22181
+ const fullPath = (0, import_path16.join)(dir, f);
22182
+ return {
22183
+ name: f.replace(/\.worldmodel\.md$/, "").replace(/\.nv-world\.md$/, ""),
22184
+ source,
22185
+ path: fullPath,
22186
+ content: (0, import_fs15.readFileSync)(fullPath, "utf-8")
22187
+ };
22188
+ });
20707
22189
  }
20708
- var KNOWN_AI_LOGINS, KNOWN_AI_CO_AUTHOR_NAMES;
20709
- var init_github2 = __esm({
20710
- "src/radiant/adapters/github.ts"() {
22190
+ var import_fs15, import_path16, import_os6;
22191
+ var init_discovery = __esm({
22192
+ "src/radiant/core/discovery.ts"() {
20711
22193
  "use strict";
20712
- init_scopes();
20713
- KNOWN_AI_LOGINS = /* @__PURE__ */ new Set([
20714
- "github-actions[bot]",
20715
- "dependabot[bot]",
20716
- "renovate[bot]",
20717
- "copilot"
20718
- ]);
20719
- KNOWN_AI_CO_AUTHOR_NAMES = /* @__PURE__ */ new Set([
20720
- "claude",
20721
- "copilot",
20722
- "cursor",
20723
- "codeium",
20724
- "tabnine",
20725
- "codex"
20726
- ]);
22194
+ import_fs15 = require("fs");
22195
+ import_path16 = require("path");
22196
+ import_os6 = require("os");
22197
+ init_extends();
20727
22198
  }
20728
22199
  });
20729
22200
 
20730
22201
  // src/radiant/adapters/exocortex.ts
20731
- function readExocortex(dirPath) {
20732
- const dir = (0, import_path13.resolve)(dirPath);
22202
+ function readExocortex(dirPath, repoName) {
22203
+ const dir = (0, import_path17.resolve)(dirPath);
20733
22204
  let filesLoaded = 0;
20734
22205
  function tryRead(...paths) {
20735
22206
  for (const p of paths) {
20736
- const full = (0, import_path13.join)(dir, p);
20737
- if ((0, import_fs12.existsSync)(full)) {
22207
+ const full = (0, import_path17.join)(dir, p);
22208
+ if ((0, import_fs16.existsSync)(full)) {
20738
22209
  try {
20739
- const content = (0, import_fs12.readFileSync)(full, "utf-8").trim();
22210
+ const content = (0, import_fs16.readFileSync)(full, "utf-8").trim();
20740
22211
  if (content) {
20741
22212
  filesLoaded++;
20742
22213
  return content;
@@ -20747,55 +22218,65 @@ function readExocortex(dirPath) {
20747
22218
  }
20748
22219
  return null;
20749
22220
  }
22221
+ const attention = tryRead("attention.md");
22222
+ const goals = tryRead("goals.md");
22223
+ const identity = tryRead("identity.md", "user.md");
22224
+ const organization = tryRead("org/organization.md", "org/src/organization.md");
22225
+ const methods = tryRead("org/methods.md", "org/src/methods.md");
22226
+ let sprint = null;
22227
+ let projectContext = null;
22228
+ if (repoName) {
22229
+ const projectPaths = [
22230
+ repoName,
22231
+ repoName.toLowerCase(),
22232
+ repoName.replace(/-/g, "_")
22233
+ ];
22234
+ for (const projectDir of projectPaths) {
22235
+ const projectSprint = tryRead(
22236
+ `${projectDir}/src/sprint.md`,
22237
+ `${projectDir}/sprint.md`
22238
+ );
22239
+ if (projectSprint) {
22240
+ sprint = projectSprint;
22241
+ break;
22242
+ }
22243
+ }
22244
+ for (const projectDir of projectPaths) {
22245
+ const roadmap = tryRead(
22246
+ `${projectDir}/roadmap.md`,
22247
+ `${projectDir}/src/roadmap.md`
22248
+ );
22249
+ if (roadmap) {
22250
+ projectContext = roadmap;
22251
+ break;
22252
+ }
22253
+ }
22254
+ }
22255
+ if (!sprint) {
22256
+ sprint = tryRead("sprint.md", "src/sprint.md");
22257
+ }
20750
22258
  const ctx = {
20751
- attention: tryRead("attention.md"),
20752
- goals: tryRead("goals.md"),
20753
- identity: tryRead("identity.md"),
20754
- sprint: tryRead("sprint.md", "src/sprint.md"),
20755
- organization: tryRead("org/organization.md", "org/src/organization.md"),
20756
- methods: tryRead("org/methods.md", "org/src/methods.md"),
22259
+ attention,
22260
+ goals,
22261
+ identity,
22262
+ sprint,
22263
+ organization,
22264
+ methods,
20757
22265
  source: dir,
20758
22266
  filesLoaded
20759
22267
  };
20760
- return ctx;
20761
- }
20762
- function formatExocortexForPrompt(ctx) {
20763
- if (ctx.filesLoaded === 0) return "";
20764
- const sections = [];
20765
- sections.push(
20766
- "## Stated Intent (from exocortex)\n\nThe following is what the person/team SAYS they are doing, focused on, and working toward. Compare this against the ACTUAL activity from GitHub. Where stated intent and observed behavior diverge, that gap is the most valuable signal in this read. Name it directly."
20767
- );
20768
- if (ctx.attention) {
20769
- sections.push(`### Current attention
20770
-
20771
- ${ctx.attention}`);
20772
- }
20773
- if (ctx.goals) {
20774
- sections.push(`### Goals
20775
-
20776
- ${ctx.goals}`);
20777
- }
20778
- if (ctx.sprint) {
20779
- sections.push(`### Sprint focus
20780
-
20781
- ${ctx.sprint}`);
20782
- }
20783
- if (ctx.identity) {
20784
- sections.push(`### Identity and values
20785
-
20786
- ${ctx.identity}`);
20787
- }
20788
- if (ctx.organization) {
20789
- sections.push(`### Organization
20790
-
20791
- ${ctx.organization}`);
20792
- }
20793
- if (ctx.methods) {
20794
- sections.push(`### Methods
22268
+ if (projectContext && ctx.sprint) {
22269
+ ctx.sprint = `${ctx.sprint}
20795
22270
 
20796
- ${ctx.methods}`);
22271
+ ---
22272
+ Project roadmap:
22273
+ ${projectContext}`;
22274
+ } else if (projectContext) {
22275
+ ctx.sprint = `Project roadmap:
22276
+ ${projectContext}`;
22277
+ ctx.filesLoaded++;
20797
22278
  }
20798
- return sections.join("\n\n");
22279
+ return ctx;
20799
22280
  }
20800
22281
  function summarizeExocortex(ctx) {
20801
22282
  if (ctx.filesLoaded === 0) return "no exocortex files found";
@@ -20808,33 +22289,33 @@ function summarizeExocortex(ctx) {
20808
22289
  if (ctx.methods) loaded.push("methods");
20809
22290
  return `${loaded.join(", ")} (${ctx.filesLoaded} files)`;
20810
22291
  }
20811
- var import_fs12, import_path13;
22292
+ var import_fs16, import_path17;
20812
22293
  var init_exocortex = __esm({
20813
22294
  "src/radiant/adapters/exocortex.ts"() {
20814
22295
  "use strict";
20815
- import_fs12 = require("fs");
20816
- import_path13 = require("path");
22296
+ import_fs16 = require("fs");
22297
+ import_path17 = require("path");
20817
22298
  }
20818
22299
  });
20819
22300
 
20820
22301
  // src/radiant/memory/palace.ts
20821
22302
  function writeRead(exocortexDir, frontmatter, text) {
20822
- const dir = (0, import_path14.resolve)(exocortexDir, "radiant", "reads");
20823
- (0, import_fs13.mkdirSync)(dir, { recursive: true });
22303
+ const dir = (0, import_path18.resolve)(exocortexDir, "radiant", "reads");
22304
+ (0, import_fs17.mkdirSync)(dir, { recursive: true });
20824
22305
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
20825
22306
  const filename = `${date}.md`;
20826
- const filepath = (0, import_path14.join)(dir, filename);
22307
+ const filepath = (0, import_path18.join)(dir, filename);
20827
22308
  const content = `${frontmatter}
20828
22309
 
20829
22310
  ${text}
20830
22311
  `;
20831
- (0, import_fs13.writeFileSync)(filepath, content, "utf-8");
22312
+ (0, import_fs17.writeFileSync)(filepath, content, "utf-8");
20832
22313
  return filepath;
20833
22314
  }
20834
22315
  function updateKnowledge(exocortexDir, persistence, options) {
20835
- const dir = (0, import_path14.resolve)(exocortexDir, "radiant");
20836
- (0, import_fs13.mkdirSync)(dir, { recursive: true });
20837
- const filepath = (0, import_path14.join)(dir, "knowledge.md");
22316
+ const dir = (0, import_path18.resolve)(exocortexDir, "radiant");
22317
+ (0, import_fs17.mkdirSync)(dir, { recursive: true });
22318
+ const filepath = (0, import_path18.join)(dir, "knowledge.md");
20838
22319
  const totalReads = options?.totalReads ?? 0;
20839
22320
  const existingUntriggered = loadUntriggeredCounts(filepath);
20840
22321
  const lines = [
@@ -20921,14 +22402,14 @@ function updateKnowledge(exocortexDir, persistence, options) {
20921
22402
  lines.push(`${name}=${count}`);
20922
22403
  }
20923
22404
  lines.push("-->");
20924
- (0, import_fs13.writeFileSync)(filepath, lines.join("\n"), "utf-8");
22405
+ (0, import_fs17.writeFileSync)(filepath, lines.join("\n"), "utf-8");
20925
22406
  return filepath;
20926
22407
  }
20927
22408
  function loadUntriggeredCounts(filepath) {
20928
22409
  const counts = /* @__PURE__ */ new Map();
20929
- if (!(0, import_fs13.existsSync)(filepath)) return counts;
22410
+ if (!(0, import_fs17.existsSync)(filepath)) return counts;
20930
22411
  try {
20931
- const content = (0, import_fs13.readFileSync)(filepath, "utf-8");
22412
+ const content = (0, import_fs17.readFileSync)(filepath, "utf-8");
20932
22413
  const match = content.match(
20933
22414
  /<!-- untriggered_counts[\s\S]*?-->/
20934
22415
  );
@@ -20946,13 +22427,13 @@ function loadUntriggeredCounts(filepath) {
20946
22427
  return counts;
20947
22428
  }
20948
22429
  function loadPriorReads(exocortexDir) {
20949
- const dir = (0, import_path14.resolve)(exocortexDir, "radiant", "reads");
20950
- if (!(0, import_fs13.existsSync)(dir)) return [];
20951
- const files = (0, import_fs13.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
22430
+ const dir = (0, import_path18.resolve)(exocortexDir, "radiant", "reads");
22431
+ if (!(0, import_fs17.existsSync)(dir)) return [];
22432
+ const files = (0, import_fs17.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
20952
22433
  const reads = [];
20953
22434
  for (const filename of files) {
20954
- const filepath = (0, import_path14.join)(dir, filename);
20955
- const content = (0, import_fs13.readFileSync)(filepath, "utf-8");
22435
+ const filepath = (0, import_path18.join)(dir, filename);
22436
+ const content = (0, import_fs17.readFileSync)(filepath, "utf-8");
20956
22437
  const date = filename.replace(".md", "");
20957
22438
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
20958
22439
  const frontmatter = fmMatch ? fmMatch[1] : "";
@@ -20986,33 +22467,12 @@ function computePersistence(priorReads, currentPatternNames) {
20986
22467
  dates: dates.sort()
20987
22468
  })).sort((a, b) => b.occurrences - a.occurrences);
20988
22469
  }
20989
- function formatPriorReadsForPrompt(priorReads) {
20990
- if (priorReads.length === 0) return "";
20991
- const lines = [
20992
- "## Prior Radiant reads (history)",
20993
- "",
20994
- `Radiant has run ${priorReads.length} time${priorReads.length > 1 ? "s" : ""} before on this scope.`,
20995
- "If you see patterns that appeared in prior reads, note their persistence.",
20996
- "Patterns that recur across 3+ reads are strong candidates for declaration in the strategy file.",
20997
- ""
20998
- ];
20999
- for (const read of priorReads.slice(-4)) {
21000
- lines.push(`### Read from ${read.date}`);
21001
- if (read.patternNames.length > 0) {
21002
- lines.push(`Patterns observed: ${read.patternNames.join(", ")}`);
21003
- } else {
21004
- lines.push("No patterns extracted from frontmatter.");
21005
- }
21006
- lines.push("");
21007
- }
21008
- return lines.join("\n");
21009
- }
21010
- var import_fs13, import_path14;
22470
+ var import_fs17, import_path18;
21011
22471
  var init_palace = __esm({
21012
22472
  "src/radiant/memory/palace.ts"() {
21013
22473
  "use strict";
21014
- import_fs13 = require("fs");
21015
- import_path14 = require("path");
22474
+ import_fs17 = require("fs");
22475
+ import_path18 = require("path");
21016
22476
  }
21017
22477
  });
21018
22478
 
@@ -21365,15 +22825,17 @@ function buildInterpretationPrompt(input) {
21365
22825
  const eventSample = formatEventSample(input.events, 30);
21366
22826
  const canonicalList = (input.canonicalPatterns ?? []).length > 0 ? `Patterns the organization has already named (use these names if you see them):
21367
22827
  ${input.canonicalPatterns.map((p) => `- ${p}`).join("\n")}` : "No patterns have been named yet. Everything you observe is new.";
22828
+ const compressedWorld = compressWorldmodel(input.worldmodelContent);
22829
+ const cl = compressLens(input.lens);
21368
22830
  const frame = input.lens.primary_frame;
21369
22831
  const evalQuestions = frame.evaluation_questions.map((q, i) => `${i + 1}. ${q}`).join("\n");
21370
- const forbiddenList = input.lens.forbidden_phrases.map((p) => `- "${p}"`).join("\n");
21371
- const jargonTable = Object.entries(input.lens.vocabulary.jargon_translations).map(([internal, plain]) => ` "${internal}" \u2192 "${plain}"`).join("\n");
22832
+ const forbiddenList = cl.forbiddenPhrases;
22833
+ const jargonTable = cl.jargonTranslations;
21372
22834
  return `You are a behavioral intelligence system reading team activity and producing a read for the reader who needs to act on it.
21373
22835
 
21374
- ## Context the reader has loaded
22836
+ ## Worldmodel (compressed)
21375
22837
 
21376
- ${input.worldmodelContent}
22838
+ ${compressedWorld}
21377
22839
 
21378
22840
  ## What happened this window
21379
22841
 
@@ -21552,6 +23014,7 @@ function isPatternLike(x) {
21552
23014
  var init_patterns = __esm({
21553
23015
  "src/radiant/core/patterns.ts"() {
21554
23016
  "use strict";
23017
+ init_compress();
21555
23018
  }
21556
23019
  });
21557
23020
 
@@ -21569,30 +23032,16 @@ Window: last ${input.windowDays} days \xB7 ${input.eventCount} events
21569
23032
  Lens: ${input.lens.name}`
21570
23033
  );
21571
23034
  if (input.patterns.length > 0) {
21572
- const canonical = input.patterns.filter((p) => p.type === "canonical");
21573
- const candidates = input.patterns.filter((p) => p.type === "candidate");
21574
23035
  let emergentBlock = "EMERGENT\n";
21575
- if (canonical.length > 0) {
21576
- for (const p of canonical) {
21577
- emergentBlock += `
23036
+ for (const p of input.patterns) {
23037
+ emergentBlock += `
21578
23038
  ${p.name}
21579
23039
  `;
21580
- emergentBlock += ` ${p.description}
21581
- `;
21582
- }
21583
- }
21584
- if (candidates.length > 0) {
21585
- emergentBlock += "\n Emergent (candidates \u2014 not yet in worldmodel)\n";
21586
- for (const p of candidates) {
21587
- emergentBlock += `
21588
- ${p.name} (candidate)
21589
- `;
21590
- emergentBlock += ` ${p.description}
23040
+ emergentBlock += ` ${p.description}
21591
23041
  `;
21592
- if (p.evidence.cited_invariant) {
21593
- emergentBlock += ` Cited invariant: ${p.evidence.cited_invariant}
23042
+ if (p.evidence.cited_invariant) {
23043
+ emergentBlock += ` Cited invariant: ${p.evidence.cited_invariant}
21594
23044
  `;
21595
- }
21596
23045
  }
21597
23046
  }
21598
23047
  sections.push(emergentBlock.trimEnd());
@@ -21811,16 +23260,29 @@ var init_renderer = __esm({
21811
23260
  async function emergent(input) {
21812
23261
  const lens = resolveLens2(input.lensId);
21813
23262
  const windowDays = input.windowDays ?? 14;
23263
+ let worldStack;
23264
+ let worldmodelContent = input.worldmodelContent;
23265
+ if (!worldmodelContent || worldmodelContent.trim() === "") {
23266
+ worldStack = discoverWorlds({ explicitWorldsDir: input.worldPath });
23267
+ worldmodelContent = worldStack.combinedContent;
23268
+ }
21814
23269
  let statedIntent;
21815
23270
  let exocortexContext;
21816
23271
  let priorReadContext = "";
21817
23272
  if (input.exocortexPath) {
21818
- exocortexContext = readExocortex(input.exocortexPath);
21819
- const formatted = formatExocortexForPrompt(exocortexContext);
21820
- if (formatted) statedIntent = formatted;
23273
+ const repoName = input.scope.type === "repo" ? input.scope.repo : void 0;
23274
+ exocortexContext = readExocortex(input.exocortexPath, repoName);
23275
+ const compressed = compressExocortex(exocortexContext);
23276
+ if (compressed) {
23277
+ statedIntent = `## Stated Intent (from exocortex, compressed)
23278
+
23279
+ ${compressed}
23280
+
23281
+ Compare stated intent against actual GitHub activity. Gaps = drift.`;
23282
+ }
21821
23283
  const priorReads = loadPriorReads(input.exocortexPath);
21822
23284
  if (priorReads.length > 0) {
21823
- priorReadContext = formatPriorReadsForPrompt(priorReads);
23285
+ priorReadContext = compressPriorReads(priorReads);
21824
23286
  }
21825
23287
  }
21826
23288
  let events;
@@ -21838,6 +23300,40 @@ async function emergent(input) {
21838
23300
  windowDays
21839
23301
  });
21840
23302
  }
23303
+ let adapterSignals = "";
23304
+ const activeAdapters = ["github"];
23305
+ const discordToken = process.env.DISCORD_TOKEN;
23306
+ const discordGuild = process.env.DISCORD_GUILD_ID;
23307
+ if (discordToken && discordGuild) {
23308
+ try {
23309
+ const discord = await fetchDiscordActivity(discordGuild, discordToken, { windowDays });
23310
+ events.push(...discord.events);
23311
+ adapterSignals += "\n\n" + formatDiscordSignalsForPrompt(discord.signals);
23312
+ activeAdapters.push("discord");
23313
+ } catch {
23314
+ }
23315
+ }
23316
+ const slackToken = process.env.SLACK_TOKEN;
23317
+ if (slackToken) {
23318
+ try {
23319
+ const slack = await fetchSlackActivity(slackToken, { windowDays });
23320
+ events.push(...slack.events);
23321
+ adapterSignals += "\n\n" + formatSlackSignalsForPrompt(slack.signals);
23322
+ activeAdapters.push("slack");
23323
+ } catch {
23324
+ }
23325
+ }
23326
+ const notionToken = process.env.NOTION_TOKEN;
23327
+ if (notionToken) {
23328
+ try {
23329
+ const notion = await fetchNotionActivity(notionToken, { windowDays });
23330
+ events.push(...notion.events);
23331
+ adapterSignals += "\n\n" + formatNotionSignalsForPrompt(notion.signals);
23332
+ activeAdapters.push("notion");
23333
+ } catch {
23334
+ }
23335
+ }
23336
+ events.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
21841
23337
  const classified = classifyEvents(events);
21842
23338
  const signals = extractSignals(classified);
21843
23339
  const scores = computeScores(signals, input.worldmodelContent !== "");
@@ -21848,7 +23344,7 @@ async function emergent(input) {
21848
23344
  lens,
21849
23345
  ai: input.ai,
21850
23346
  canonicalPatterns: input.canonicalPatterns,
21851
- statedIntent: statedIntent ? statedIntent + (priorReadContext ? "\n\n" + priorReadContext : "") : priorReadContext || void 0
23347
+ statedIntent: [statedIntent, adapterSignals, priorReadContext].filter(Boolean).join("\n\n") || void 0
21852
23348
  });
21853
23349
  const rewrittenPatterns = patterns.map((p) => lens.rewrite(p));
21854
23350
  const allDescriptions = rewrittenPatterns.map((p) => p.description).join("\n");
@@ -21897,7 +23393,9 @@ async function emergent(input) {
21897
23393
  voiceClean: voiceViolations.length === 0,
21898
23394
  signals,
21899
23395
  scores,
21900
- eventCount: events.length
23396
+ eventCount: events.length,
23397
+ activeAdapters,
23398
+ worldStack
21901
23399
  };
21902
23400
  }
21903
23401
  function computeScores(signals, worldmodelLoaded) {
@@ -21952,8 +23450,13 @@ var init_emergent = __esm({
21952
23450
  "use strict";
21953
23451
  init_lenses();
21954
23452
  init_github2();
23453
+ init_discord();
23454
+ init_slack();
23455
+ init_notion();
23456
+ init_discovery();
21955
23457
  init_exocortex();
21956
23458
  init_palace();
23459
+ init_compress();
21957
23460
  init_governance();
21958
23461
  init_signals();
21959
23462
  init_math();
@@ -22010,22 +23513,22 @@ __export(server_exports, {
22010
23513
  startRadiantMcp: () => startRadiantMcp
22011
23514
  });
22012
23515
  function loadWorldmodelContent(worldsPath) {
22013
- const resolved = (0, import_path15.resolve)(worldsPath);
22014
- if (!(0, import_fs14.existsSync)(resolved)) {
23516
+ const resolved = (0, import_path19.resolve)(worldsPath);
23517
+ if (!(0, import_fs18.existsSync)(resolved)) {
22015
23518
  throw new Error(`Worlds path not found: ${resolved}`);
22016
23519
  }
22017
- const stat = (0, import_fs14.statSync)(resolved);
23520
+ const stat = (0, import_fs18.statSync)(resolved);
22018
23521
  if (stat.isFile()) {
22019
- return (0, import_fs14.readFileSync)(resolved, "utf-8");
23522
+ return (0, import_fs18.readFileSync)(resolved, "utf-8");
22020
23523
  }
22021
23524
  if (stat.isDirectory()) {
22022
- const files = (0, import_fs14.readdirSync)(resolved).filter(
22023
- (f) => (0, import_path15.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
23525
+ const files = (0, import_fs18.readdirSync)(resolved).filter(
23526
+ (f) => (0, import_path19.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
22024
23527
  ).sort();
22025
23528
  if (files.length === 0) {
22026
23529
  throw new Error(`No worldmodel files found in ${resolved}`);
22027
23530
  }
22028
- return files.map((f) => (0, import_fs14.readFileSync)((0, import_path15.join)(resolved, f), "utf-8")).join("\n\n---\n\n");
23531
+ return files.map((f) => (0, import_fs18.readFileSync)((0, import_path19.join)(resolved, f), "utf-8")).join("\n\n---\n\n");
22029
23532
  }
22030
23533
  throw new Error(`Worlds path is neither a file nor directory: ${resolved}`);
22031
23534
  }
@@ -22044,12 +23547,12 @@ async function startRadiantMcp(args) {
22044
23547
  const server = new RadiantMcpServer({ worldsPath, lensId, model });
22045
23548
  await server.start();
22046
23549
  }
22047
- var import_fs14, import_path15, TOOLS, RadiantMcpServer;
23550
+ var import_fs18, import_path19, TOOLS, RadiantMcpServer;
22048
23551
  var init_server = __esm({
22049
23552
  "src/radiant/mcp/server.ts"() {
22050
23553
  "use strict";
22051
- import_fs14 = require("fs");
22052
- import_path15 = require("path");
23554
+ import_fs18 = require("fs");
23555
+ import_path19 = require("path");
22053
23556
  init_think();
22054
23557
  init_emergent();
22055
23558
  init_ai();
@@ -22338,17 +23841,17 @@ function parseArgs27(argv) {
22338
23841
  return result;
22339
23842
  }
22340
23843
  function loadWorldmodelContent2(worldsPath) {
22341
- const resolved = (0, import_path16.resolve)(worldsPath);
22342
- if (!(0, import_fs15.existsSync)(resolved)) {
23844
+ const resolved = (0, import_path20.resolve)(worldsPath);
23845
+ if (!(0, import_fs19.existsSync)(resolved)) {
22343
23846
  throw new Error(`Worlds path not found: ${resolved}`);
22344
23847
  }
22345
- const stat = (0, import_fs15.statSync)(resolved);
23848
+ const stat = (0, import_fs19.statSync)(resolved);
22346
23849
  if (stat.isFile()) {
22347
- return (0, import_fs15.readFileSync)(resolved, "utf-8");
23850
+ return (0, import_fs19.readFileSync)(resolved, "utf-8");
22348
23851
  }
22349
23852
  if (stat.isDirectory()) {
22350
- const files = (0, import_fs15.readdirSync)(resolved).filter(
22351
- (f) => (0, import_path16.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
23853
+ const files = (0, import_fs19.readdirSync)(resolved).filter(
23854
+ (f) => (0, import_path20.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
22352
23855
  ).sort();
22353
23856
  if (files.length === 0) {
22354
23857
  throw new Error(
@@ -22356,27 +23859,55 @@ function loadWorldmodelContent2(worldsPath) {
22356
23859
  );
22357
23860
  }
22358
23861
  return files.map((f) => {
22359
- const content = (0, import_fs15.readFileSync)((0, import_path16.join)(resolved, f), "utf-8");
23862
+ const content = (0, import_fs19.readFileSync)((0, import_path20.join)(resolved, f), "utf-8");
22360
23863
  return `<!-- worldmodel: ${f} -->
22361
23864
  ${content}`;
22362
23865
  }).join("\n\n---\n\n");
22363
23866
  }
22364
23867
  throw new Error(`Worlds path is neither a file nor a directory: ${resolved}`);
22365
23868
  }
22366
- async function cmdThink(args) {
22367
- const lensId = args.lens ?? process.env.RADIANT_LENS;
22368
- if (!lensId) {
23869
+ function resolveWorldmodelContent(explicitPath, scopeOwner) {
23870
+ if (explicitPath) {
23871
+ return loadWorldmodelContent2(explicitPath);
23872
+ }
23873
+ const stack = discoverWorlds({
23874
+ repoDir: process.cwd(),
23875
+ scopeOwner
23876
+ });
23877
+ if (stack.worlds.length === 0) {
23878
+ const scopeLine = scopeOwner ? ` 3. github:${scopeOwner}/worlds (from scope arg)
23879
+ ` : "";
23880
+ const ext = scopeOwner ? 4 : 3;
23881
+ const repo = scopeOwner ? 5 : 4;
22369
23882
  process.stderr.write(
22370
- `${RED2}Error:${RESET3} --lens <id> or RADIANT_LENS required.
22371
- ${DIM3}Available lenses: ${listLenses().join(", ")}${RESET3}
23883
+ `${RED2}Error:${RESET3} No worldmodel found.
23884
+ ${DIM3}Tried (in order):
23885
+ 1. ~/.neuroverse/worlds/ (user tier)
23886
+ 2. github:<owner>/worlds (org auto-detect from git remote)
23887
+ ` + scopeLine + ` ${ext}. .neuroverse/config.json extends (explicit shared worlds)
23888
+ ${repo}. ./worlds/ or ./.neuroverse/worlds/ (repo tier)
23889
+
23890
+ Pass --worlds <dir> or set RADIANT_WORLDS to specify explicitly.
23891
+ Or run against a <scope>/ where github.com/<scope>/worlds exists.${RESET3}
22372
23892
  `
22373
23893
  );
22374
23894
  process.exit(1);
22375
23895
  }
22376
- const worldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
22377
- if (!worldsPath) {
23896
+ process.stderr.write(`${DIM3}${formatActiveWorlds(stack)}${RESET3}
23897
+
23898
+ `);
23899
+ for (const warning of stack.warnings) {
23900
+ process.stderr.write(`${YELLOW3}\u26A0${RESET3} ${warning}
23901
+ `);
23902
+ }
23903
+ return stack.combinedContent;
23904
+ }
23905
+ async function cmdThink(args) {
23906
+ const lensId = args.lens ?? process.env.RADIANT_LENS;
23907
+ if (!lensId) {
22378
23908
  process.stderr.write(
22379
- `${RED2}Error:${RESET3} --worlds <dir> or RADIANT_WORLDS required.
23909
+ `${RED2}Error:${RESET3} --lens <id> or RADIANT_LENS required.
23910
+ ${DIM3}Available lenses: ${listLenses().join(", ")}${RESET3}
22380
23911
  `
22381
23912
  );
22382
23913
  process.exit(1);
@@ -22395,7 +23926,7 @@ ${DIM3}Set it to your Anthropic API key to use Radiant's AI features.${RESET3}
22395
23926
  query = args.rest.join(" ");
22396
23927
  }
22397
23928
  if (!query && !process.stdin.isTTY) {
22398
- query = (0, import_fs15.readFileSync)(0, "utf-8").trim();
23929
+ query = (0, import_fs19.readFileSync)(0, "utf-8").trim();
22399
23930
  }
22400
23931
  if (!query) {
22401
23932
  process.stderr.write(
@@ -22405,12 +23936,12 @@ ${DIM3}Use --query "...", pass as trailing args, or pipe via stdin.${RESET3}
22405
23936
  );
22406
23937
  process.exit(1);
22407
23938
  }
22408
- const worldmodelContent = loadWorldmodelContent2(worldsPath);
23939
+ const explicitWorldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
23940
+ const worldmodelContent = resolveWorldmodelContent(explicitWorldsPath);
22409
23941
  const model = args.model ?? process.env.RADIANT_MODEL;
22410
23942
  const ai = createAnthropicAI(apiKey, model || void 0);
22411
23943
  process.stderr.write(
22412
- `${DIM3}Worlds: ${worldsPath}${RESET3}
22413
- ${DIM3}Lens: ${lensId}${RESET3}
23944
+ `${DIM3}Lens: ${lensId}${RESET3}
22414
23945
  ${DIM3}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET3}
22415
23946
 
22416
23947
  `
@@ -22469,14 +24000,6 @@ async function cmdEmergent(args) {
22469
24000
  process.stderr.write(
22470
24001
  `${RED2}Error:${RESET3} --lens <id> or RADIANT_LENS required.
22471
24002
  ${DIM3}Available lenses: ${listLenses().join(", ")}${RESET3}
22472
- `
22473
- );
22474
- process.exit(1);
22475
- }
22476
- const worldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
22477
- if (!worldsPath) {
22478
- process.stderr.write(
22479
- `${RED2}Error:${RESET3} --worlds <dir> or RADIANT_WORLDS required.
22480
24003
  `
22481
24004
  );
22482
24005
  process.exit(1);
@@ -22498,7 +24021,11 @@ ${DIM3}Set it to a GitHub PAT with repo read access.${RESET3}
22498
24021
  );
22499
24022
  process.exit(1);
22500
24023
  }
22501
- const worldmodelContent = loadWorldmodelContent2(worldsPath);
24024
+ const explicitWorldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
24025
+ const worldmodelContent = resolveWorldmodelContent(
24026
+ explicitWorldsPath,
24027
+ scope.owner
24028
+ );
22502
24029
  const model = args.model ?? process.env.RADIANT_MODEL;
22503
24030
  const ai = createAnthropicAI(anthropicKey, model || void 0);
22504
24031
  const view = args.view ?? process.env.RADIANT_VIEW ?? "community";
@@ -22672,18 +24199,19 @@ async function main34(argv) {
22672
24199
  process.exit(1);
22673
24200
  }
22674
24201
  }
22675
- var import_fs15, import_path16, RED2, DIM3, BOLD3, YELLOW3, RESET3, USAGE10;
24202
+ var import_fs19, import_path20, RED2, DIM3, BOLD3, YELLOW3, RESET3, USAGE10;
22676
24203
  var init_radiant = __esm({
22677
24204
  "src/cli/radiant.ts"() {
22678
24205
  "use strict";
22679
- import_fs15 = require("fs");
22680
- import_path16 = require("path");
24206
+ import_fs19 = require("fs");
24207
+ import_path20 = require("path");
22681
24208
  init_think();
22682
24209
  init_emergent();
22683
24210
  init_ai();
22684
24211
  init_scopes();
22685
24212
  init_exocortex();
22686
24213
  init_lenses();
24214
+ init_discovery();
22687
24215
  RED2 = "\x1B[31m";
22688
24216
  DIM3 = "\x1B[2m";
22689
24217
  BOLD3 = "\x1B[1m";
@@ -22709,6 +24237,18 @@ ${BOLD3}Usage:${RESET3}
22709
24237
  neuroverse radiant lenses list
22710
24238
  neuroverse radiant lenses describe auki-builder
22711
24239
 
24240
+ ${BOLD3}Auto-discovery:${RESET3}
24241
+ You do not need to clone the target repo.
24242
+
24243
+ radiant emergent NeuroverseOS/ \u2192 probes github.com/NeuroverseOS/worlds
24244
+ radiant emergent aukiverse/posemesh \u2192 probes github.com/aukiverse/worlds
24245
+
24246
+ The scope argument itself is enough. Discovery also picks up
24247
+ ~/.neuroverse/worlds/ (personal), the org from your current clone's
24248
+ .git/config (if any), and ./worlds/ (this repo).
24249
+
24250
+ Set NEUROVERSE_NO_ORG=1 to disable org probing for a single run.
24251
+
22712
24252
  ${BOLD3}Environment:${RESET3}
22713
24253
  ANTHROPIC_API_KEY Required for AI commands (think, emergent, decision)
22714
24254
  RADIANT_WORLDS Default worlds directory (overridden by --worlds)