@neuroverseos/governance 0.8.1 → 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.
@@ -477,7 +477,7 @@ function sovereignConduitRewrite(pattern) {
477
477
  return {
478
478
  ...pattern,
479
479
  framing: "what this means for the people in the system",
480
- emphasis: "humanity + sovereignty + learning",
480
+ emphasis: "humanity + agency + learning",
481
481
  compress: false
482
482
  };
483
483
  }
@@ -488,17 +488,17 @@ var init_sovereign_conduit = __esm({
488
488
  SOVEREIGN_CONDUIT_FRAME = {
489
489
  domains: [
490
490
  "stewardship",
491
- "sovereignty",
491
+ "agency",
492
492
  "integration"
493
493
  ],
494
494
  overlaps: [
495
495
  {
496
- domains: ["stewardship", "sovereignty"],
496
+ domains: ["stewardship", "agency"],
497
497
  emergent_state: "Trust",
498
498
  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."
499
499
  },
500
500
  {
501
- domains: ["sovereignty", "integration"],
501
+ domains: ["agency", "integration"],
502
502
  emergent_state: "Possibility",
503
503
  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."
504
504
  },
@@ -529,7 +529,7 @@ var init_sovereign_conduit = __esm({
529
529
  "harm detection",
530
530
  "constraint design"
531
531
  ],
532
- "sovereignty": [
532
+ "agency": [
533
533
  "independent thinking",
534
534
  "decision ownership",
535
535
  "self-trust",
@@ -553,7 +553,7 @@ var init_sovereign_conduit = __esm({
553
553
  output_translation: {
554
554
  never_surface_in_output: [
555
555
  "Stewardship",
556
- "Sovereignty",
556
+ "Agency",
557
557
  "Integration"
558
558
  ],
559
559
  surface_freely: [
@@ -568,7 +568,7 @@ var init_sovereign_conduit = __esm({
568
568
  external_expression: "the boundaries are clear and the system feels safe to operate inside"
569
569
  },
570
570
  {
571
- internal_reasoning: "Sovereignty is weakening",
571
+ internal_reasoning: "Agency is weakening",
572
572
  external_expression: "decision ownership is quietly shifting \u2014 the human is accepting AI output without engaging with it"
573
573
  },
574
574
  {
@@ -651,12 +651,12 @@ var init_sovereign_conduit = __esm({
651
651
  close_with_strategic_frame: "preferred",
652
652
  punchline_move: "sparing",
653
653
  honesty_about_failure: "required",
654
- output_translation: `Reason internally through the three-domain frame (Stewardship, Sovereignty, 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.`
654
+ 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.`
655
655
  };
656
656
  SOVEREIGN_CONDUIT_FORBIDDEN = Object.freeze([
657
657
  // Bucket names as labels
658
658
  "stewardship is",
659
- "sovereignty is",
659
+ "agency is",
660
660
  "integration is",
661
661
  // AI-assistant hedging
662
662
  "it may be beneficial to consider",
@@ -692,7 +692,7 @@ var init_sovereign_conduit = __esm({
692
692
  "Here's what's actually happening: [plain explanation].",
693
693
  "The question to ask yourself: [question].",
694
694
  "The difference between [A] and [B] matters here: [why].",
695
- // Sovereignty checks
695
+ // Agency checks
696
696
  "Are you still the author of this decision, or did the AI make it for you?",
697
697
  "The AI extended your thinking here. That's working.",
698
698
  "The AI replaced your thinking here. That's the drift to watch.",
@@ -703,7 +703,7 @@ var init_sovereign_conduit = __esm({
703
703
  ]);
704
704
  SOVEREIGN_CONDUIT_STRATEGIC = Object.freeze([
705
705
  "Safety before expansion \u2014 always. No exception.",
706
- "Sovereignty before convenience \u2014 the right to think for yourself is not a feature to optimize away.",
706
+ "Agency before convenience \u2014 the right to think for yourself is not a feature to optimize away.",
707
707
  "Extension, not replacement \u2014 AI should make your thinking bigger, not do your thinking for you.",
708
708
  "Diversity over uniformity \u2014 different thinkers produce different ideas, and that's the engine of progress.",
709
709
  "The rules should be visible \u2014 like a good house, you know the rules before you walk in.",
@@ -713,16 +713,16 @@ var init_sovereign_conduit = __esm({
713
713
  ]);
714
714
  SOVEREIGN_CONDUIT_EXEMPLARS = Object.freeze([
715
715
  {
716
- path: "neuroverseos-sovereign-conduit.worldmodel.md",
716
+ path: "src/radiant/examples/neuroverse-base/neuroverseos-sovereign-conduit.worldmodel.md",
717
717
  title: "The Sovereign Conduit Worldmodel",
718
- exhibits: ["stewardship", "sovereignty", "integration"],
718
+ exhibits: ["stewardship", "agency", "integration"],
719
719
  integration_quality: "full \u2014 all three domains defined, overlaps named, center identity declared",
720
720
  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.'
721
721
  }
722
722
  ]);
723
723
  sovereignConduitLens = {
724
724
  name: "sovereign-conduit",
725
- description: "The NeuroVerseOS base lens. Warm, accessible, teaching. Evaluates activity through Stewardship (safety), Sovereignty (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.",
725
+ 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.",
726
726
  primary_frame: {
727
727
  domains: SOVEREIGN_CONDUIT_FRAME.domains,
728
728
  overlaps: SOVEREIGN_CONDUIT_FRAME.overlaps,
@@ -1670,82 +1670,382 @@ var init_notion = __esm({
1670
1670
  }
1671
1671
  });
1672
1672
 
1673
+ // src/radiant/core/git-remote.ts
1674
+ function resolveGitConfigPath(repoDir) {
1675
+ const dotGit = (0, import_path.join)(repoDir, ".git");
1676
+ if (!(0, import_fs.existsSync)(dotGit)) return null;
1677
+ try {
1678
+ const stat = (0, import_fs.statSync)(dotGit);
1679
+ if (stat.isDirectory()) {
1680
+ return (0, import_path.join)(dotGit, "config");
1681
+ }
1682
+ if (stat.isFile()) {
1683
+ const content = (0, import_fs.readFileSync)(dotGit, "utf-8");
1684
+ const match = /^gitdir:\s*(.+)$/m.exec(content);
1685
+ if (!match) return null;
1686
+ const gitDir = (0, import_path.resolve)(repoDir, match[1].trim());
1687
+ const configPath = (0, import_path.join)(gitDir, "config");
1688
+ return (0, import_fs.existsSync)(configPath) ? configPath : null;
1689
+ }
1690
+ } catch {
1691
+ return null;
1692
+ }
1693
+ return null;
1694
+ }
1695
+ function readOriginRemote(repoDir) {
1696
+ const configPath = resolveGitConfigPath(repoDir);
1697
+ if (!configPath) return null;
1698
+ try {
1699
+ const raw = (0, import_fs.readFileSync)(configPath, "utf-8");
1700
+ const sectionRe = /\[remote "origin"\]\s*\n((?:(?!\[)[^\n]*\n?)*)/;
1701
+ const section = sectionRe.exec(raw);
1702
+ if (!section) return null;
1703
+ const urlRe = /^\s*url\s*=\s*(.+?)\s*$/m;
1704
+ const url = urlRe.exec(section[1]);
1705
+ return url ? url[1] : null;
1706
+ } catch {
1707
+ return null;
1708
+ }
1709
+ }
1710
+ function parseRemoteUrl(url) {
1711
+ const trimmed = url.trim();
1712
+ if (!trimmed) return null;
1713
+ const ssh = /^git@([^:]+):([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
1714
+ if (ssh) return { host: ssh[1], owner: ssh[2], repo: ssh[3] };
1715
+ const sshProto = /^ssh:\/\/git@([^/]+)\/([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
1716
+ if (sshProto) return { host: sshProto[1], owner: sshProto[2], repo: sshProto[3] };
1717
+ const https = /^https?:\/\/(?:[^@/]+@)?([^/]+)\/([^/]+)\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
1718
+ if (https) return { host: https[1], owner: https[2], repo: https[3] };
1719
+ return null;
1720
+ }
1721
+ function getRepoOrigin(repoDir) {
1722
+ const url = readOriginRemote(repoDir);
1723
+ if (!url) return null;
1724
+ return parseRemoteUrl(url);
1725
+ }
1726
+ var import_fs, import_path;
1727
+ var init_git_remote = __esm({
1728
+ "src/radiant/core/git-remote.ts"() {
1729
+ "use strict";
1730
+ import_fs = require("fs");
1731
+ import_path = require("path");
1732
+ }
1733
+ });
1734
+
1735
+ // src/radiant/core/extends.ts
1736
+ function loadExtendsConfig(repoDir) {
1737
+ const configPath = (0, import_path2.join)(repoDir, ".neuroverse", "config.json");
1738
+ if (!(0, import_fs2.existsSync)(configPath)) return null;
1739
+ try {
1740
+ const raw = (0, import_fs2.readFileSync)(configPath, "utf-8");
1741
+ const parsed = JSON.parse(raw);
1742
+ return parsed;
1743
+ } catch {
1744
+ return null;
1745
+ }
1746
+ }
1747
+ function parseExtendsSpec(raw) {
1748
+ const trimmed = raw.trim();
1749
+ if (!trimmed) return null;
1750
+ if (trimmed.startsWith("github:")) {
1751
+ const rest = trimmed.slice("github:".length);
1752
+ const match = /^([^/]+)\/([^@:]+)(?:@([^:]+))?(?::(.+))?$/.exec(rest);
1753
+ if (!match) return null;
1754
+ return {
1755
+ raw: trimmed,
1756
+ kind: "github",
1757
+ owner: match[1],
1758
+ repo: match[2],
1759
+ ref: match[3] ?? "HEAD",
1760
+ subpath: match[4] ?? ""
1761
+ };
1762
+ }
1763
+ if (trimmed.startsWith("./") || trimmed.startsWith("../") || (0, import_path2.isAbsolute)(trimmed)) {
1764
+ return { raw: trimmed, kind: "local", path: trimmed };
1765
+ }
1766
+ return null;
1767
+ }
1768
+ function getCacheDir(spec, baseCacheDir) {
1769
+ const root = baseCacheDir ?? (0, import_path2.join)((0, import_os.homedir)(), ".neuroverse", "cache", "extends");
1770
+ const key = (0, import_crypto.createHash)("sha256").update(spec.raw).digest("hex").slice(0, 16);
1771
+ return (0, import_path2.join)(root, key);
1772
+ }
1773
+ function isCacheFresh(cacheDir, ttlMs) {
1774
+ const stampPath = (0, import_path2.join)(cacheDir, ".neuroverse-fetched");
1775
+ if (!(0, import_fs2.existsSync)(stampPath)) return false;
1776
+ try {
1777
+ const stamp = (0, import_fs2.statSync)(stampPath);
1778
+ return Date.now() - stamp.mtimeMs < ttlMs;
1779
+ } catch {
1780
+ return false;
1781
+ }
1782
+ }
1783
+ function markCacheFresh(cacheDir) {
1784
+ const stampPath = (0, import_path2.join)(cacheDir, ".neuroverse-fetched");
1785
+ try {
1786
+ (0, import_fs2.mkdirSync)(cacheDir, { recursive: true });
1787
+ (0, import_fs2.writeFileSync)(stampPath, (/* @__PURE__ */ new Date()).toISOString());
1788
+ } catch {
1789
+ }
1790
+ }
1791
+ function resolveExtendsSpec(spec, repoDir, options) {
1792
+ if (spec.kind === "local") {
1793
+ const full = (0, import_path2.isAbsolute)(spec.path) ? spec.path : (0, import_path2.resolve)(repoDir, spec.path);
1794
+ if (!(0, import_fs2.existsSync)(full)) {
1795
+ return { spec, dir: null, warning: `local extends path not found: ${full}` };
1796
+ }
1797
+ return { spec, dir: full };
1798
+ }
1799
+ const cacheRoot = options?.cacheDir;
1800
+ const ttl = options?.ttlMs ?? DEFAULT_TTL_MS;
1801
+ const cacheDir = getCacheDir(spec, cacheRoot);
1802
+ const fresh = isCacheFresh(cacheDir, ttl);
1803
+ const needsFetch = options?.forceRefresh || !fresh || !(0, import_fs2.existsSync)(cacheDir);
1804
+ if (needsFetch && options?.noFetch) {
1805
+ if ((0, import_fs2.existsSync)(cacheDir) && (0, import_fs2.existsSync)((0, import_path2.join)(cacheDir, ".neuroverse-fetched"))) {
1806
+ return resolveSubpath(spec, cacheDir);
1807
+ }
1808
+ return options?.silentOnMissing ? { spec, dir: null } : { spec, dir: null, warning: `NEUROVERSE_NO_FETCH set and no cache for ${spec.raw}` };
1809
+ }
1810
+ if (needsFetch) {
1811
+ const fetcher = options?.fetcher ?? defaultGitFetcher;
1812
+ try {
1813
+ fetcher(spec, cacheDir);
1814
+ markCacheFresh(cacheDir);
1815
+ } catch (err) {
1816
+ if ((0, import_fs2.existsSync)(cacheDir) && (0, import_fs2.existsSync)((0, import_path2.join)(cacheDir, ".neuroverse-fetched"))) {
1817
+ const result = resolveSubpath(spec, cacheDir);
1818
+ return options?.silentOnMissing ? result : { ...result, warning: `fetch failed for ${spec.raw}, using stale cache: ${err.message}` };
1819
+ }
1820
+ return options?.silentOnMissing ? { spec, dir: null } : { spec, dir: null, warning: `fetch failed for ${spec.raw}: ${err.message}` };
1821
+ }
1822
+ }
1823
+ return resolveSubpath(spec, cacheDir);
1824
+ }
1825
+ function resolveSubpath(spec, cacheDir) {
1826
+ const target = spec.subpath ? (0, import_path2.join)(cacheDir, spec.subpath) : cacheDir;
1827
+ if (!(0, import_fs2.existsSync)(target)) {
1828
+ return { spec, dir: null, warning: `subpath not found in ${spec.raw}: ${spec.subpath}` };
1829
+ }
1830
+ if (!spec.subpath) {
1831
+ const candidates = [
1832
+ (0, import_path2.join)(target, "worlds"),
1833
+ (0, import_path2.join)(target, ".neuroverse", "worlds")
1834
+ ];
1835
+ for (const c of candidates) {
1836
+ if ((0, import_fs2.existsSync)(c)) return { spec, dir: c };
1837
+ }
1838
+ }
1839
+ return { spec, dir: target };
1840
+ }
1841
+ function detectOrgExtendsSpec(repoDir) {
1842
+ const origin = getRepoOrigin(repoDir);
1843
+ if (!origin) return null;
1844
+ if (origin.host !== "github.com") return null;
1845
+ if (origin.repo === "worlds") return null;
1846
+ return {
1847
+ raw: `github:${origin.owner}/worlds`,
1848
+ kind: "github",
1849
+ owner: origin.owner,
1850
+ repo: "worlds",
1851
+ ref: "HEAD",
1852
+ subpath: ""
1853
+ };
1854
+ }
1855
+ function resolveAllExtends(repoDir, options) {
1856
+ const config = options?.config !== void 0 ? options.config : loadExtendsConfig(repoDir);
1857
+ if (!config?.extends || config.extends.length === 0) return [];
1858
+ const results = [];
1859
+ for (const raw of config.extends) {
1860
+ const spec = parseExtendsSpec(raw);
1861
+ if (!spec) {
1862
+ results.push({
1863
+ spec: { raw, kind: "local" },
1864
+ dir: null,
1865
+ warning: `unparseable extends spec: ${raw}`
1866
+ });
1867
+ continue;
1868
+ }
1869
+ results.push(resolveExtendsSpec(spec, repoDir, options));
1870
+ }
1871
+ return results;
1872
+ }
1873
+ var import_fs2, import_path2, import_os, import_crypto, import_child_process, DEFAULT_TTL_MS, defaultGitFetcher;
1874
+ var init_extends = __esm({
1875
+ "src/radiant/core/extends.ts"() {
1876
+ "use strict";
1877
+ import_fs2 = require("fs");
1878
+ import_path2 = require("path");
1879
+ import_os = require("os");
1880
+ import_crypto = require("crypto");
1881
+ import_child_process = require("child_process");
1882
+ init_git_remote();
1883
+ DEFAULT_TTL_MS = 60 * 60 * 1e3;
1884
+ defaultGitFetcher = (spec, destDir) => {
1885
+ if (spec.kind !== "github") return;
1886
+ const url = `https://github.com/${spec.owner}/${spec.repo}.git`;
1887
+ const parent = (0, import_path2.resolve)(destDir, "..");
1888
+ (0, import_fs2.mkdirSync)(parent, { recursive: true });
1889
+ if ((0, import_fs2.existsSync)(destDir)) {
1890
+ (0, import_fs2.rmSync)(destDir, { recursive: true, force: true });
1891
+ }
1892
+ const args = ["clone", "--depth", "1", "--filter=blob:none"];
1893
+ if (spec.ref && spec.ref !== "HEAD") {
1894
+ args.push("--branch", spec.ref);
1895
+ }
1896
+ args.push(url, destDir);
1897
+ (0, import_child_process.execFileSync)("git", args, { stdio: "pipe" });
1898
+ };
1899
+ }
1900
+ });
1901
+
1673
1902
  // src/radiant/core/discovery.ts
1674
1903
  function discoverWorlds(options) {
1675
1904
  const worlds = [];
1676
- const userDir = options?.userWorldsDir ?? (0, import_path.join)((0, import_os.homedir)(), ".neuroverse", "worlds");
1677
- if ((0, import_fs.existsSync)(userDir)) {
1905
+ const warnings = [];
1906
+ const forceRefresh = process.env.NEUROVERSE_REFRESH === "1";
1907
+ const noFetch = process.env.NEUROVERSE_NO_FETCH === "1";
1908
+ const noOrg = options?.disableOrg || process.env.NEUROVERSE_NO_ORG === "1";
1909
+ const userDir = options?.userWorldsDir ?? (0, import_path3.join)((0, import_os2.homedir)(), ".neuroverse", "worlds");
1910
+ if ((0, import_fs3.existsSync)(userDir)) {
1678
1911
  worlds.push(...loadWorldsFromDir(userDir, "user"));
1679
1912
  }
1913
+ if (!noOrg && !options?.explicitWorldsDir) {
1914
+ const specs = [];
1915
+ if (options?.repoDir) {
1916
+ const fromGit = detectOrgExtendsSpec(options.repoDir);
1917
+ if (fromGit) specs.push(fromGit);
1918
+ }
1919
+ if (options?.scopeOwner) {
1920
+ const already = specs.some(
1921
+ (s) => s.owner?.toLowerCase() === options.scopeOwner.toLowerCase()
1922
+ );
1923
+ if (!already) {
1924
+ specs.push({
1925
+ raw: `github:${options.scopeOwner}/worlds`,
1926
+ kind: "github",
1927
+ owner: options.scopeOwner,
1928
+ repo: "worlds"
1929
+ });
1930
+ }
1931
+ }
1932
+ const baseDir = options?.repoDir ?? process.cwd();
1933
+ for (const spec of specs) {
1934
+ const result = resolveExtendsSpec(spec, baseDir, {
1935
+ cacheDir: options?.extendsCacheDir,
1936
+ fetcher: options?.extendsFetcher,
1937
+ ttlMs: options?.extendsTtlMs,
1938
+ forceRefresh,
1939
+ noFetch,
1940
+ silentOnMissing: true
1941
+ });
1942
+ worlds.push(...loadExtendsWorlds(result, "org"));
1943
+ }
1944
+ }
1945
+ if (options?.repoDir && !options.disableExtends && !options.explicitWorldsDir) {
1946
+ const results = resolveAllExtends(options.repoDir, {
1947
+ cacheDir: options.extendsCacheDir,
1948
+ fetcher: options.extendsFetcher,
1949
+ ttlMs: options.extendsTtlMs,
1950
+ forceRefresh,
1951
+ noFetch
1952
+ });
1953
+ for (const result of results) {
1954
+ worlds.push(...loadExtendsWorlds(result, "extends"));
1955
+ if (result.warning) warnings.push(result.warning);
1956
+ }
1957
+ }
1680
1958
  if (options?.explicitWorldsDir) {
1681
1959
  worlds.push(...loadWorldsFromDir(options.explicitWorldsDir, "repo"));
1682
1960
  } else if (options?.repoDir) {
1683
1961
  const repoPaths = [
1684
- (0, import_path.join)(options.repoDir, "worlds"),
1685
- (0, import_path.join)(options.repoDir, ".neuroverse", "worlds")
1962
+ (0, import_path3.join)(options.repoDir, "worlds"),
1963
+ (0, import_path3.join)(options.repoDir, ".neuroverse", "worlds")
1686
1964
  ];
1687
1965
  for (const p of repoPaths) {
1688
- if ((0, import_fs.existsSync)(p)) {
1966
+ if ((0, import_fs3.existsSync)(p)) {
1689
1967
  worlds.push(...loadWorldsFromDir(p, "repo"));
1690
1968
  break;
1691
1969
  }
1692
1970
  }
1693
1971
  }
1694
- const combinedContent = worlds.map((w) => `<!-- world: ${w.name} (${w.source}) -->
1695
- ${w.content}`).join("\n\n---\n\n");
1972
+ const combinedContent = worlds.map((w) => {
1973
+ const tag = w.extendsFrom ? `<!-- world: ${w.name} (${w.source} ${w.extendsFrom}) -->` : `<!-- world: ${w.name} (${w.source}) -->`;
1974
+ return `${tag}
1975
+ ${w.content}`;
1976
+ }).join("\n\n---\n\n");
1696
1977
  const summary = worlds.length === 0 ? "no worlds discovered" : worlds.map((w) => `${w.name} (${w.source})`).join(", ");
1697
- return { worlds, combinedContent, summary };
1978
+ return { worlds, combinedContent, summary, warnings };
1979
+ }
1980
+ function formatActiveWorlds(stack) {
1981
+ if (stack.worlds.length === 0) return "No worlds loaded.";
1982
+ const lines = ["ACTIVE WORLDS", ""];
1983
+ for (const w of stack.worlds) {
1984
+ 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";
1985
+ lines.push(` ${w.name} (${sourceLabel})`);
1986
+ }
1987
+ if (stack.warnings.length > 0) {
1988
+ lines.push("", "WARNINGS");
1989
+ for (const w of stack.warnings) lines.push(` ${w}`);
1990
+ }
1991
+ return lines.join("\n");
1992
+ }
1993
+ function loadExtendsWorlds(result, source) {
1994
+ if (!result.dir) return [];
1995
+ const loaded = loadWorldsFromDir(result.dir, source);
1996
+ return loaded.map((w) => ({ ...w, extendsFrom: result.spec.raw }));
1698
1997
  }
1699
1998
  function loadWorldsFromDir(dirPath, source) {
1700
- const dir = (0, import_path.resolve)(dirPath);
1701
- if (!(0, import_fs.existsSync)(dir)) return [];
1702
- const stat = (0, import_fs.statSync)(dir);
1999
+ const dir = (0, import_path3.resolve)(dirPath);
2000
+ if (!(0, import_fs3.existsSync)(dir)) return [];
2001
+ const stat = (0, import_fs3.statSync)(dir);
1703
2002
  if (stat.isFile() && dir.endsWith(".md")) {
1704
2003
  try {
1705
2004
  return [{
1706
- name: (0, import_path.basename)(dir).replace(/\.worldmodel\.md$/, "").replace(/\.nv-world\.md$/, ""),
2005
+ name: (0, import_path3.basename)(dir).replace(/\.worldmodel\.md$/, "").replace(/\.nv-world\.md$/, ""),
1707
2006
  source,
1708
2007
  path: dir,
1709
- content: (0, import_fs.readFileSync)(dir, "utf-8")
2008
+ content: (0, import_fs3.readFileSync)(dir, "utf-8")
1710
2009
  }];
1711
2010
  } catch {
1712
2011
  return [];
1713
2012
  }
1714
2013
  }
1715
2014
  if (!stat.isDirectory()) return [];
1716
- const files = (0, import_fs.readdirSync)(dir).filter(
2015
+ const files = (0, import_fs3.readdirSync)(dir).filter(
1717
2016
  (f) => f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md")
1718
2017
  ).sort();
1719
2018
  return files.map((f) => {
1720
- const fullPath = (0, import_path.join)(dir, f);
2019
+ const fullPath = (0, import_path3.join)(dir, f);
1721
2020
  return {
1722
2021
  name: f.replace(/\.worldmodel\.md$/, "").replace(/\.nv-world\.md$/, ""),
1723
2022
  source,
1724
2023
  path: fullPath,
1725
- content: (0, import_fs.readFileSync)(fullPath, "utf-8")
2024
+ content: (0, import_fs3.readFileSync)(fullPath, "utf-8")
1726
2025
  };
1727
2026
  });
1728
2027
  }
1729
- var import_fs, import_path, import_os;
2028
+ var import_fs3, import_path3, import_os2;
1730
2029
  var init_discovery = __esm({
1731
2030
  "src/radiant/core/discovery.ts"() {
1732
2031
  "use strict";
1733
- import_fs = require("fs");
1734
- import_path = require("path");
1735
- import_os = require("os");
2032
+ import_fs3 = require("fs");
2033
+ import_path3 = require("path");
2034
+ import_os2 = require("os");
2035
+ init_extends();
1736
2036
  }
1737
2037
  });
1738
2038
 
1739
2039
  // src/radiant/adapters/exocortex.ts
1740
2040
  function readExocortex(dirPath, repoName) {
1741
- const dir = (0, import_path2.resolve)(dirPath);
2041
+ const dir = (0, import_path4.resolve)(dirPath);
1742
2042
  let filesLoaded = 0;
1743
2043
  function tryRead(...paths) {
1744
2044
  for (const p of paths) {
1745
- const full = (0, import_path2.join)(dir, p);
1746
- if ((0, import_fs2.existsSync)(full)) {
2045
+ const full = (0, import_path4.join)(dir, p);
2046
+ if ((0, import_fs4.existsSync)(full)) {
1747
2047
  try {
1748
- const content = (0, import_fs2.readFileSync)(full, "utf-8").trim();
2048
+ const content = (0, import_fs4.readFileSync)(full, "utf-8").trim();
1749
2049
  if (content) {
1750
2050
  filesLoaded++;
1751
2051
  return content;
@@ -1827,33 +2127,33 @@ function summarizeExocortex(ctx) {
1827
2127
  if (ctx.methods) loaded.push("methods");
1828
2128
  return `${loaded.join(", ")} (${ctx.filesLoaded} files)`;
1829
2129
  }
1830
- var import_fs2, import_path2;
2130
+ var import_fs4, import_path4;
1831
2131
  var init_exocortex = __esm({
1832
2132
  "src/radiant/adapters/exocortex.ts"() {
1833
2133
  "use strict";
1834
- import_fs2 = require("fs");
1835
- import_path2 = require("path");
2134
+ import_fs4 = require("fs");
2135
+ import_path4 = require("path");
1836
2136
  }
1837
2137
  });
1838
2138
 
1839
2139
  // src/radiant/memory/palace.ts
1840
2140
  function writeRead(exocortexDir, frontmatter, text) {
1841
- const dir = (0, import_path3.resolve)(exocortexDir, "radiant", "reads");
1842
- (0, import_fs3.mkdirSync)(dir, { recursive: true });
2141
+ const dir = (0, import_path5.resolve)(exocortexDir, "radiant", "reads");
2142
+ (0, import_fs5.mkdirSync)(dir, { recursive: true });
1843
2143
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1844
2144
  const filename = `${date}.md`;
1845
- const filepath = (0, import_path3.join)(dir, filename);
2145
+ const filepath = (0, import_path5.join)(dir, filename);
1846
2146
  const content = `${frontmatter}
1847
2147
 
1848
2148
  ${text}
1849
2149
  `;
1850
- (0, import_fs3.writeFileSync)(filepath, content, "utf-8");
2150
+ (0, import_fs5.writeFileSync)(filepath, content, "utf-8");
1851
2151
  return filepath;
1852
2152
  }
1853
2153
  function updateKnowledge(exocortexDir, persistence, options) {
1854
- const dir = (0, import_path3.resolve)(exocortexDir, "radiant");
1855
- (0, import_fs3.mkdirSync)(dir, { recursive: true });
1856
- const filepath = (0, import_path3.join)(dir, "knowledge.md");
2154
+ const dir = (0, import_path5.resolve)(exocortexDir, "radiant");
2155
+ (0, import_fs5.mkdirSync)(dir, { recursive: true });
2156
+ const filepath = (0, import_path5.join)(dir, "knowledge.md");
1857
2157
  const totalReads = options?.totalReads ?? 0;
1858
2158
  const existingUntriggered = loadUntriggeredCounts(filepath);
1859
2159
  const lines = [
@@ -1940,14 +2240,14 @@ function updateKnowledge(exocortexDir, persistence, options) {
1940
2240
  lines.push(`${name}=${count}`);
1941
2241
  }
1942
2242
  lines.push("-->");
1943
- (0, import_fs3.writeFileSync)(filepath, lines.join("\n"), "utf-8");
2243
+ (0, import_fs5.writeFileSync)(filepath, lines.join("\n"), "utf-8");
1944
2244
  return filepath;
1945
2245
  }
1946
2246
  function loadUntriggeredCounts(filepath) {
1947
2247
  const counts = /* @__PURE__ */ new Map();
1948
- if (!(0, import_fs3.existsSync)(filepath)) return counts;
2248
+ if (!(0, import_fs5.existsSync)(filepath)) return counts;
1949
2249
  try {
1950
- const content = (0, import_fs3.readFileSync)(filepath, "utf-8");
2250
+ const content = (0, import_fs5.readFileSync)(filepath, "utf-8");
1951
2251
  const match = content.match(
1952
2252
  /<!-- untriggered_counts[\s\S]*?-->/
1953
2253
  );
@@ -1965,13 +2265,13 @@ function loadUntriggeredCounts(filepath) {
1965
2265
  return counts;
1966
2266
  }
1967
2267
  function loadPriorReads(exocortexDir) {
1968
- const dir = (0, import_path3.resolve)(exocortexDir, "radiant", "reads");
1969
- if (!(0, import_fs3.existsSync)(dir)) return [];
1970
- const files = (0, import_fs3.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
2268
+ const dir = (0, import_path5.resolve)(exocortexDir, "radiant", "reads");
2269
+ if (!(0, import_fs5.existsSync)(dir)) return [];
2270
+ const files = (0, import_fs5.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
1971
2271
  const reads = [];
1972
2272
  for (const filename of files) {
1973
- const filepath = (0, import_path3.join)(dir, filename);
1974
- const content = (0, import_fs3.readFileSync)(filepath, "utf-8");
2273
+ const filepath = (0, import_path5.join)(dir, filename);
2274
+ const content = (0, import_fs5.readFileSync)(filepath, "utf-8");
1975
2275
  const date = filename.replace(".md", "");
1976
2276
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
1977
2277
  const frontmatter = fmMatch ? fmMatch[1] : "";
@@ -2005,12 +2305,12 @@ function computePersistence(priorReads, currentPatternNames) {
2005
2305
  dates: dates.sort()
2006
2306
  })).sort((a, b) => b.occurrences - a.occurrences);
2007
2307
  }
2008
- var import_fs3, import_path3;
2308
+ var import_fs5, import_path5;
2009
2309
  var init_palace = __esm({
2010
2310
  "src/radiant/memory/palace.ts"() {
2011
2311
  "use strict";
2012
- import_fs3 = require("fs");
2013
- import_path3 = require("path");
2312
+ import_fs5 = require("fs");
2313
+ import_path5 = require("path");
2014
2314
  }
2015
2315
  });
2016
2316
 
@@ -3119,10 +3419,10 @@ var init_guard_engine = __esm({
3119
3419
  // src/loader/world-loader.ts
3120
3420
  async function loadWorldFromDirectory(dirPath) {
3121
3421
  const { readFile } = await import("fs/promises");
3122
- const { join: join6 } = await import("path");
3422
+ const { join: join8 } = await import("path");
3123
3423
  const { readdirSync: readdirSync6 } = await import("fs");
3124
3424
  async function readJson(filename) {
3125
- const filePath = join6(dirPath, filename);
3425
+ const filePath = join8(dirPath, filename);
3126
3426
  try {
3127
3427
  const content = await readFile(filePath, "utf-8");
3128
3428
  return JSON.parse(content);
@@ -3152,11 +3452,11 @@ async function loadWorldFromDirectory(dirPath) {
3152
3452
  const metadataJson = await readJson("metadata.json");
3153
3453
  const rules = [];
3154
3454
  try {
3155
- const rulesDir = join6(dirPath, "rules");
3455
+ const rulesDir = join8(dirPath, "rules");
3156
3456
  const ruleFiles = readdirSync6(rulesDir).filter((f) => f.endsWith(".json")).sort();
3157
3457
  for (const file of ruleFiles) {
3158
3458
  try {
3159
- const content = await readFile(join6(rulesDir, file), "utf-8");
3459
+ const content = await readFile(join8(rulesDir, file), "utf-8");
3160
3460
  rules.push(JSON.parse(content));
3161
3461
  } catch (err) {
3162
3462
  process.stderr.write(
@@ -4251,22 +4551,22 @@ __export(server_exports, {
4251
4551
  startRadiantMcp: () => startRadiantMcp
4252
4552
  });
4253
4553
  function loadWorldmodelContent(worldsPath) {
4254
- const resolved = (0, import_path4.resolve)(worldsPath);
4255
- if (!(0, import_fs4.existsSync)(resolved)) {
4554
+ const resolved = (0, import_path6.resolve)(worldsPath);
4555
+ if (!(0, import_fs6.existsSync)(resolved)) {
4256
4556
  throw new Error(`Worlds path not found: ${resolved}`);
4257
4557
  }
4258
- const stat = (0, import_fs4.statSync)(resolved);
4558
+ const stat = (0, import_fs6.statSync)(resolved);
4259
4559
  if (stat.isFile()) {
4260
- return (0, import_fs4.readFileSync)(resolved, "utf-8");
4560
+ return (0, import_fs6.readFileSync)(resolved, "utf-8");
4261
4561
  }
4262
4562
  if (stat.isDirectory()) {
4263
- const files = (0, import_fs4.readdirSync)(resolved).filter(
4264
- (f) => (0, import_path4.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
4563
+ const files = (0, import_fs6.readdirSync)(resolved).filter(
4564
+ (f) => (0, import_path6.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
4265
4565
  ).sort();
4266
4566
  if (files.length === 0) {
4267
4567
  throw new Error(`No worldmodel files found in ${resolved}`);
4268
4568
  }
4269
- return files.map((f) => (0, import_fs4.readFileSync)((0, import_path4.join)(resolved, f), "utf-8")).join("\n\n---\n\n");
4569
+ return files.map((f) => (0, import_fs6.readFileSync)((0, import_path6.join)(resolved, f), "utf-8")).join("\n\n---\n\n");
4270
4570
  }
4271
4571
  throw new Error(`Worlds path is neither a file nor directory: ${resolved}`);
4272
4572
  }
@@ -4285,12 +4585,12 @@ async function startRadiantMcp(args) {
4285
4585
  const server = new RadiantMcpServer({ worldsPath, lensId, model });
4286
4586
  await server.start();
4287
4587
  }
4288
- var import_fs4, import_path4, TOOLS, RadiantMcpServer;
4588
+ var import_fs6, import_path6, TOOLS, RadiantMcpServer;
4289
4589
  var init_server = __esm({
4290
4590
  "src/radiant/mcp/server.ts"() {
4291
4591
  "use strict";
4292
- import_fs4 = require("fs");
4293
- import_path4 = require("path");
4592
+ import_fs6 = require("fs");
4593
+ import_path6 = require("path");
4294
4594
  init_think();
4295
4595
  init_emergent();
4296
4596
  init_ai();
@@ -4521,14 +4821,15 @@ __export(radiant_exports, {
4521
4821
  main: () => main
4522
4822
  });
4523
4823
  module.exports = __toCommonJS(radiant_exports);
4524
- var import_fs5 = require("fs");
4525
- var import_path5 = require("path");
4824
+ var import_fs7 = require("fs");
4825
+ var import_path7 = require("path");
4526
4826
  init_think();
4527
4827
  init_emergent();
4528
4828
  init_ai();
4529
4829
  init_scopes();
4530
4830
  init_exocortex();
4531
4831
  init_lenses();
4832
+ init_discovery();
4532
4833
  var RED = "\x1B[31m";
4533
4834
  var DIM = "\x1B[2m";
4534
4835
  var BOLD = "\x1B[1m";
@@ -4554,6 +4855,18 @@ ${BOLD}Usage:${RESET}
4554
4855
  neuroverse radiant lenses list
4555
4856
  neuroverse radiant lenses describe auki-builder
4556
4857
 
4858
+ ${BOLD}Auto-discovery:${RESET}
4859
+ You do not need to clone the target repo.
4860
+
4861
+ radiant emergent NeuroverseOS/ \u2192 probes github.com/NeuroverseOS/worlds
4862
+ radiant emergent aukiverse/posemesh \u2192 probes github.com/aukiverse/worlds
4863
+
4864
+ The scope argument itself is enough. Discovery also picks up
4865
+ ~/.neuroverse/worlds/ (personal), the org from your current clone's
4866
+ .git/config (if any), and ./worlds/ (this repo).
4867
+
4868
+ Set NEUROVERSE_NO_ORG=1 to disable org probing for a single run.
4869
+
4557
4870
  ${BOLD}Environment:${RESET}
4558
4871
  ANTHROPIC_API_KEY Required for AI commands (think, emergent, decision)
4559
4872
  RADIANT_WORLDS Default worlds directory (overridden by --worlds)
@@ -4620,17 +4933,17 @@ function parseArgs(argv) {
4620
4933
  return result;
4621
4934
  }
4622
4935
  function loadWorldmodelContent2(worldsPath) {
4623
- const resolved = (0, import_path5.resolve)(worldsPath);
4624
- if (!(0, import_fs5.existsSync)(resolved)) {
4936
+ const resolved = (0, import_path7.resolve)(worldsPath);
4937
+ if (!(0, import_fs7.existsSync)(resolved)) {
4625
4938
  throw new Error(`Worlds path not found: ${resolved}`);
4626
4939
  }
4627
- const stat = (0, import_fs5.statSync)(resolved);
4940
+ const stat = (0, import_fs7.statSync)(resolved);
4628
4941
  if (stat.isFile()) {
4629
- return (0, import_fs5.readFileSync)(resolved, "utf-8");
4942
+ return (0, import_fs7.readFileSync)(resolved, "utf-8");
4630
4943
  }
4631
4944
  if (stat.isDirectory()) {
4632
- const files = (0, import_fs5.readdirSync)(resolved).filter(
4633
- (f) => (0, import_path5.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
4945
+ const files = (0, import_fs7.readdirSync)(resolved).filter(
4946
+ (f) => (0, import_path7.extname)(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
4634
4947
  ).sort();
4635
4948
  if (files.length === 0) {
4636
4949
  throw new Error(
@@ -4638,27 +4951,55 @@ function loadWorldmodelContent2(worldsPath) {
4638
4951
  );
4639
4952
  }
4640
4953
  return files.map((f) => {
4641
- const content = (0, import_fs5.readFileSync)((0, import_path5.join)(resolved, f), "utf-8");
4954
+ const content = (0, import_fs7.readFileSync)((0, import_path7.join)(resolved, f), "utf-8");
4642
4955
  return `<!-- worldmodel: ${f} -->
4643
4956
  ${content}`;
4644
4957
  }).join("\n\n---\n\n");
4645
4958
  }
4646
4959
  throw new Error(`Worlds path is neither a file nor a directory: ${resolved}`);
4647
4960
  }
4648
- async function cmdThink(args) {
4649
- const lensId = args.lens ?? process.env.RADIANT_LENS;
4650
- if (!lensId) {
4961
+ function resolveWorldmodelContent(explicitPath, scopeOwner) {
4962
+ if (explicitPath) {
4963
+ return loadWorldmodelContent2(explicitPath);
4964
+ }
4965
+ const stack = discoverWorlds({
4966
+ repoDir: process.cwd(),
4967
+ scopeOwner
4968
+ });
4969
+ if (stack.worlds.length === 0) {
4970
+ const scopeLine = scopeOwner ? ` 3. github:${scopeOwner}/worlds (from scope arg)
4971
+ ` : "";
4972
+ const ext = scopeOwner ? 4 : 3;
4973
+ const repo = scopeOwner ? 5 : 4;
4651
4974
  process.stderr.write(
4652
- `${RED}Error:${RESET} --lens <id> or RADIANT_LENS required.
4653
- ${DIM}Available lenses: ${listLenses().join(", ")}${RESET}
4975
+ `${RED}Error:${RESET} No worldmodel found.
4976
+ ${DIM}Tried (in order):
4977
+ 1. ~/.neuroverse/worlds/ (user tier)
4978
+ 2. github:<owner>/worlds (org auto-detect from git remote)
4979
+ ` + scopeLine + ` ${ext}. .neuroverse/config.json extends (explicit shared worlds)
4980
+ ${repo}. ./worlds/ or ./.neuroverse/worlds/ (repo tier)
4981
+
4982
+ Pass --worlds <dir> or set RADIANT_WORLDS to specify explicitly.
4983
+ Or run against a <scope>/ where github.com/<scope>/worlds exists.${RESET}
4654
4984
  `
4655
4985
  );
4656
4986
  process.exit(1);
4657
4987
  }
4658
- const worldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
4659
- if (!worldsPath) {
4988
+ process.stderr.write(`${DIM}${formatActiveWorlds(stack)}${RESET}
4989
+
4990
+ `);
4991
+ for (const warning of stack.warnings) {
4992
+ process.stderr.write(`${YELLOW}\u26A0${RESET} ${warning}
4993
+ `);
4994
+ }
4995
+ return stack.combinedContent;
4996
+ }
4997
+ async function cmdThink(args) {
4998
+ const lensId = args.lens ?? process.env.RADIANT_LENS;
4999
+ if (!lensId) {
4660
5000
  process.stderr.write(
4661
- `${RED}Error:${RESET} --worlds <dir> or RADIANT_WORLDS required.
5001
+ `${RED}Error:${RESET} --lens <id> or RADIANT_LENS required.
5002
+ ${DIM}Available lenses: ${listLenses().join(", ")}${RESET}
4662
5003
  `
4663
5004
  );
4664
5005
  process.exit(1);
@@ -4677,7 +5018,7 @@ ${DIM}Set it to your Anthropic API key to use Radiant's AI features.${RESET}
4677
5018
  query = args.rest.join(" ");
4678
5019
  }
4679
5020
  if (!query && !process.stdin.isTTY) {
4680
- query = (0, import_fs5.readFileSync)(0, "utf-8").trim();
5021
+ query = (0, import_fs7.readFileSync)(0, "utf-8").trim();
4681
5022
  }
4682
5023
  if (!query) {
4683
5024
  process.stderr.write(
@@ -4687,12 +5028,12 @@ ${DIM}Use --query "...", pass as trailing args, or pipe via stdin.${RESET}
4687
5028
  );
4688
5029
  process.exit(1);
4689
5030
  }
4690
- const worldmodelContent = loadWorldmodelContent2(worldsPath);
5031
+ const explicitWorldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
5032
+ const worldmodelContent = resolveWorldmodelContent(explicitWorldsPath);
4691
5033
  const model = args.model ?? process.env.RADIANT_MODEL;
4692
5034
  const ai = createAnthropicAI(apiKey, model || void 0);
4693
5035
  process.stderr.write(
4694
- `${DIM}Worlds: ${worldsPath}${RESET}
4695
- ${DIM}Lens: ${lensId}${RESET}
5036
+ `${DIM}Lens: ${lensId}${RESET}
4696
5037
  ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
4697
5038
 
4698
5039
  `
@@ -4751,14 +5092,6 @@ async function cmdEmergent(args) {
4751
5092
  process.stderr.write(
4752
5093
  `${RED}Error:${RESET} --lens <id> or RADIANT_LENS required.
4753
5094
  ${DIM}Available lenses: ${listLenses().join(", ")}${RESET}
4754
- `
4755
- );
4756
- process.exit(1);
4757
- }
4758
- const worldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
4759
- if (!worldsPath) {
4760
- process.stderr.write(
4761
- `${RED}Error:${RESET} --worlds <dir> or RADIANT_WORLDS required.
4762
5095
  `
4763
5096
  );
4764
5097
  process.exit(1);
@@ -4780,7 +5113,11 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
4780
5113
  );
4781
5114
  process.exit(1);
4782
5115
  }
4783
- const worldmodelContent = loadWorldmodelContent2(worldsPath);
5116
+ const explicitWorldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
5117
+ const worldmodelContent = resolveWorldmodelContent(
5118
+ explicitWorldsPath,
5119
+ scope.owner
5120
+ );
4784
5121
  const model = args.model ?? process.env.RADIANT_MODEL;
4785
5122
  const ai = createAnthropicAI(anthropicKey, model || void 0);
4786
5123
  const view = args.view ?? process.env.RADIANT_VIEW ?? "community";