@neuroverseos/governance 0.7.0 → 0.8.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.
package/README.md CHANGED
@@ -3,12 +3,51 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@neuroverseos/governance)](https://www.npmjs.com/package/@neuroverseos/governance)
4
4
  [![license](https://img.shields.io/npm/l/@neuroverseos/governance)](LICENSE.md)
5
5
 
6
- **Control what AI can doand how it behaves across every app.**
6
+ **Behavioral governance for AI systems.** Give meaning to behavior meaning relative to the behavioral models that have been declared and governed.
7
7
 
8
- NeuroVerse is the governance layer for AI-powered devices. It gives users, developers, and organizations a single system to define permissions, behavioral personality, and role-based accessfor smart glasses, phones, agents, or any AI-enabled product.
8
+ Human intelligence and artificial intelligence are two different kinds of intelligence working together. All organizations, all systems, gather people around declared shared intent. NeuroverseOS tools help define those intentions into behaviors and those behaviors become a constitution carried out at runtime.
9
9
 
10
- **Built for multi-agent systems:** when many agents are active, they all evaluate against the same deterministic governance model.
11
- **Built for handoff:** governance is portable as world/plan artifacts, so teams can update policy quickly and hand it across agents, apps, and operators without rewriting core logic.
10
+ NeuroverseOS is the universe where human and AI meet to work together, defined by the behaviors the organization has agreed upon. **Radiant** is the behavioral intelligence layer built on top: it reads what happened, compares it against what was declared, and tells you where the work aligns and where it drifts.
11
+
12
+ Together they put you in a cocoon of behavior — not a cage, a cocoon. Something that holds your shape while you're becoming what you said you'd become.
13
+
14
+ ## Two products, one package
15
+
16
+ | Layer | What it does | Who uses it |
17
+ |---|---|---|
18
+ | **NeuroverseOS** | Governance engine — worldmodel compiler, guard engine, lens system, plan enforcement | Developers building governed AI apps |
19
+ | **Radiant** | Behavioral intelligence — reads activity, gives it meaning through the worldmodel, measures human-AI alignment | Teams and organizations (starting with Auki/ExoCortex) |
20
+
21
+ Both ship in `@neuroverseos/governance`. Install once, use either or both.
22
+
23
+ ## Radiant — behavioral intelligence for collaboration
24
+
25
+ Radiant gives meaning to behavior. It reads activity (GitHub commits, PRs, reviews), classifies each event by who did it (human, AI, or both together), extracts behavioral signals, identifies patterns through AI interpretation governed by the worldmodel, and produces a structured read:
26
+
27
+ ```bash
28
+ npx @neuroverseos/governance radiant emergent aukiverse/posemesh \
29
+ --lens auki-builder --worlds ./worlds/
30
+ ```
31
+
32
+ Output:
33
+
34
+ ```
35
+ EMERGENT — what patterns are visible in the team's work
36
+ MEANING — what it means against the worldmodel
37
+ MOVE — what to do about it (or "nothing's broken, keep shipping")
38
+ ALIGNMENT — L/C/N/R scores (human, AI, collaboration, composite)
39
+ GOVERNANCE — audit trail: which events triggered governance, on which side
40
+ DEPTH — what Radiant can see now vs what unlocks with more reads
41
+ ```
42
+
43
+ Three scores nobody else measures:
44
+ - **L** — is the human's work aligned with the declared model?
45
+ - **C** — is the AI's output aligned with the declared model?
46
+ - **N** — when human and AI work together, is shared meaning preserved through the worldmodel? This score only exists because the worldmodel exists.
47
+
48
+ For the full Radiant documentation, see [`src/radiant/examples/auki/README.md`](src/radiant/examples/auki/README.md).
49
+
50
+ ## Governance engine — deterministic rules for AI
12
51
 
13
52
  ```
14
53
  What AI can do → Rules (permissions)
@@ -145,17 +145,30 @@ function resolveLens(id) {
145
145
  }
146
146
 
147
147
  // src/radiant/core/scopes.ts
148
- function parseRepoScope(scope) {
148
+ function parseScope(scope) {
149
149
  const cleaned = scope.replace(/^https?:\/\//, "").replace(/^github\.com\//, "").replace(/\.git$/, "").replace(/\/$/, "");
150
- const parts = cleaned.split("/");
151
- if (parts.length < 2 || !parts[0] || !parts[1]) {
150
+ const parts = cleaned.split("/").filter(Boolean);
151
+ if (parts.length === 0 || !parts[0]) {
152
152
  throw new Error(
153
- `Cannot parse repo scope: "${scope}". Expected "owner/repo" or a GitHub URL.`
153
+ `Cannot parse scope: "${scope}". Expected "owner/repo" or "owner".`
154
154
  );
155
155
  }
156
- return { owner: parts[0], repo: parts[1] };
156
+ if (parts.length === 1) {
157
+ return { type: "org", owner: parts[0] };
158
+ }
159
+ return { type: "repo", owner: parts[0], repo: parts[1] };
160
+ }
161
+ function parseRepoScope(scope) {
162
+ const parsed = parseScope(scope);
163
+ if (parsed.type === "org") {
164
+ throw new Error(
165
+ `Expected "owner/repo" but got org-level scope "${parsed.owner}". Use parseScope() for org-level.`
166
+ );
167
+ }
168
+ return parsed;
157
169
  }
158
170
  function formatScope(scope) {
171
+ if (scope.type === "org") return `${scope.owner} (org)`;
159
172
  return `${scope.owner}/${scope.repo}`;
160
173
  }
161
174
 
@@ -339,12 +352,46 @@ async function fetchJSON(url, headers) {
339
352
  }
340
353
  return await res.json();
341
354
  }
355
+ async function fetchGitHubOrgActivity(scope, token, options = {}) {
356
+ const perPage = options.perPage ?? 100;
357
+ const headers = {
358
+ Authorization: `token ${token}`,
359
+ Accept: "application/vnd.github.v3+json",
360
+ "User-Agent": "neuroverseos-radiant"
361
+ };
362
+ const repos = await fetchJSON(
363
+ `https://api.github.com/orgs/${scope.owner}/repos?sort=pushed&direction=desc&per_page=${perPage}`,
364
+ headers
365
+ );
366
+ const windowDays = options.windowDays ?? 14;
367
+ const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
368
+ const activeRepos = repos.filter(
369
+ (r) => new Date(r.pushed_at) >= since
370
+ );
371
+ const cappedRepos = activeRepos.slice(0, 10);
372
+ const allEvents = [];
373
+ const repoNames = [];
374
+ for (const repo of cappedRepos) {
375
+ const [owner, repoName] = repo.full_name.split("/");
376
+ try {
377
+ const repoScope = { type: "repo", owner, repo: repoName };
378
+ const events = await fetchGitHubActivity(repoScope, token, options);
379
+ allEvents.push(...events);
380
+ if (events.length > 0) repoNames.push(repo.full_name);
381
+ } catch {
382
+ }
383
+ }
384
+ allEvents.sort(
385
+ (a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
386
+ );
387
+ return { events: allEvents, repos: repoNames };
388
+ }
342
389
  function createMockGitHubAdapter(fixedEvents) {
343
390
  return async () => fixedEvents;
344
391
  }
345
392
 
346
393
  // src/radiant/adapters/exocortex.ts
347
- import { readFileSync, existsSync } from "fs";
394
+ import { readFileSync, existsSync, readdirSync, statSync } from "fs";
348
395
  import { join, resolve } from "path";
349
396
  function readExocortex(dirPath) {
350
397
  const dir = resolve(dirPath);
@@ -415,6 +462,46 @@ ${ctx.methods}`);
415
462
  }
416
463
  return sections.join("\n\n");
417
464
  }
465
+ function readTeamExocortices(teamDir) {
466
+ const dir = resolve(teamDir);
467
+ if (!existsSync(dir)) return [];
468
+ const entries = readdirSync(dir);
469
+ const results = [];
470
+ for (const entry of entries) {
471
+ const entryPath = join(dir, entry);
472
+ try {
473
+ const stat = statSync(entryPath);
474
+ if (stat.isDirectory()) {
475
+ const ctx = readExocortex(entryPath);
476
+ if (ctx.filesLoaded > 0) {
477
+ results.push({ name: entry, context: ctx });
478
+ }
479
+ }
480
+ } catch {
481
+ }
482
+ }
483
+ return results;
484
+ }
485
+ function formatTeamExocorticesForPrompt(team) {
486
+ if (team.length === 0) return "";
487
+ const sections = [
488
+ "## Team Intent (cross-exocortex read)",
489
+ "",
490
+ `Reading ${team.length} team members' exocortices. Compare each person's`,
491
+ "stated intent against the observed activity AND against each other.",
492
+ "Surface: duplicate focus, missing coverage, silent pivots,",
493
+ "and areas where no one is carrying the work.",
494
+ ""
495
+ ];
496
+ for (const { name, context } of team) {
497
+ sections.push(`### ${name}`);
498
+ if (context.attention) sections.push(`**Attention:** ${context.attention.split("\n")[0]}`);
499
+ if (context.goals) sections.push(`**Goals:** ${context.goals.split("\n").slice(0, 3).join("; ")}`);
500
+ if (context.sprint) sections.push(`**Sprint:** ${context.sprint.split("\n").slice(0, 3).join("; ")}`);
501
+ sections.push("");
502
+ }
503
+ return sections.join("\n");
504
+ }
418
505
  function summarizeExocortex(ctx) {
419
506
  if (ctx.filesLoaded === 0) return "no exocortex files found";
420
507
  const loaded = [];
@@ -428,7 +515,7 @@ function summarizeExocortex(ctx) {
428
515
  }
429
516
 
430
517
  // src/radiant/memory/palace.ts
431
- import { readFileSync as readFileSync2, writeFileSync, mkdirSync, readdirSync, existsSync as existsSync2 } from "fs";
518
+ import { readFileSync as readFileSync2, writeFileSync, mkdirSync, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
432
519
  import { join as join2, resolve as resolve2 } from "path";
433
520
  function writeRead(exocortexDir, frontmatter, text) {
434
521
  const dir = resolve2(exocortexDir, "radiant", "reads");
@@ -560,7 +647,7 @@ function loadUntriggeredCounts(filepath) {
560
647
  function loadPriorReads(exocortexDir) {
561
648
  const dir = resolve2(exocortexDir, "radiant", "reads");
562
649
  if (!existsSync2(dir)) return [];
563
- const files = readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
650
+ const files = readdirSync2(dir).filter((f) => f.endsWith(".md")).sort();
564
651
  const reads = [];
565
652
  for (const filename of files) {
566
653
  const filepath = join2(dir, filename);
@@ -995,6 +1082,14 @@ ${jargonTable}
995
1082
 
996
1083
  For example: don't say "update the worldmodel." Say "add a line to your strategy file."
997
1084
 
1085
+ ## When the same invariant keeps firing
1086
+
1087
+ If the prior read history or the current evidence shows the same worldmodel invariant being triggered repeatedly (by the same side \u2014 human or AI), name it in MEANING and ask the real question:
1088
+
1089
+ "This invariant has been tested N times across M reads. Always on the [human/AI] side. Either the team needs alignment on WHY this rule exists \u2014 or the team is telling you something the worldmodel hasn't absorbed yet."
1090
+
1091
+ Don't just say "invariant held." Say what it means that people keep pushing against the same wall.
1092
+
998
1093
  ## Health is a valid read
999
1094
 
1000
1095
  If the activity is healthy and aligned with the worldmodel, SAY SO. Don't fabricate problems. Over-prescription is a voice failure. Legitimate outputs include:
@@ -1379,9 +1474,21 @@ async function emergent(input) {
1379
1474
  priorReadContext = formatPriorReadsForPrompt(priorReads);
1380
1475
  }
1381
1476
  }
1382
- const events = await fetchGitHubActivity(input.scope, input.githubToken, {
1383
- windowDays
1384
- });
1477
+ let events;
1478
+ let orgRepos;
1479
+ if (input.scope.type === "org") {
1480
+ const orgResult = await fetchGitHubOrgActivity(
1481
+ input.scope,
1482
+ input.githubToken,
1483
+ { windowDays }
1484
+ );
1485
+ events = orgResult.events;
1486
+ orgRepos = orgResult.repos;
1487
+ } else {
1488
+ events = await fetchGitHubActivity(input.scope, input.githubToken, {
1489
+ windowDays
1490
+ });
1491
+ }
1385
1492
  const classified = classifyEvents(events);
1386
1493
  const signals = extractSignals(classified);
1387
1494
  const scores = computeScores(signals, input.worldmodelContent !== "");
@@ -1537,12 +1644,16 @@ export {
1537
1644
  composeSystemPrompt,
1538
1645
  checkForbiddenPhrases,
1539
1646
  think,
1647
+ parseScope,
1540
1648
  parseRepoScope,
1541
1649
  formatScope,
1542
1650
  fetchGitHubActivity,
1651
+ fetchGitHubOrgActivity,
1543
1652
  createMockGitHubAdapter,
1544
1653
  readExocortex,
1545
1654
  formatExocortexForPrompt,
1655
+ readTeamExocortices,
1656
+ formatTeamExocorticesForPrompt,
1546
1657
  summarizeExocortex,
1547
1658
  writeRead,
1548
1659
  updateKnowledge,
@@ -2003,7 +2003,7 @@ __export(world_loader_exports, {
2003
2003
  async function loadWorldFromDirectory(dirPath) {
2004
2004
  const { readFile: readFile4 } = await import("fs/promises");
2005
2005
  const { join: join18 } = await import("path");
2006
- const { readdirSync: readdirSync9 } = await import("fs");
2006
+ const { readdirSync: readdirSync10 } = await import("fs");
2007
2007
  async function readJson(filename) {
2008
2008
  const filePath = join18(dirPath, filename);
2009
2009
  try {
@@ -2036,7 +2036,7 @@ async function loadWorldFromDirectory(dirPath) {
2036
2036
  const rules = [];
2037
2037
  try {
2038
2038
  const rulesDir = join18(dirPath, "rules");
2039
- const ruleFiles = readdirSync9(rulesDir).filter((f) => f.endsWith(".json")).sort();
2039
+ const ruleFiles = readdirSync10(rulesDir).filter((f) => f.endsWith(".json")).sort();
2040
2040
  for (const file of ruleFiles) {
2041
2041
  try {
2042
2042
  const content = await readFile4(join18(rulesDir, file), "utf-8");
@@ -2183,12 +2183,12 @@ async function addGuard(worldDir, input) {
2183
2183
  async function addRule(worldDir, input) {
2184
2184
  const { readFile: readFile4, writeFile: writeFile6, mkdir: mkdir3 } = await import("fs/promises");
2185
2185
  const { join: join18 } = await import("path");
2186
- const { readdirSync: readdirSync9 } = await import("fs");
2186
+ const { readdirSync: readdirSync10 } = await import("fs");
2187
2187
  const rulesDir = join18(worldDir, "rules");
2188
2188
  await mkdir3(rulesDir, { recursive: true });
2189
2189
  let nextNum = 1;
2190
2190
  try {
2191
- const existing = readdirSync9(rulesDir).filter((f) => f.match(/^rule-\d+\.json$/)).sort();
2191
+ const existing = readdirSync10(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/);
@@ -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: basename4 } = await import("path");
2852
+ const { join: pathJoin, extname: extname4, basename: basename5 } = 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: basename4(inputPath), content }];
2856
+ return [{ filename: basename5(inputPath), content }];
2857
2857
  }
2858
2858
  if (stats.isDirectory()) {
2859
2859
  const sources = [];
2860
- await collectDir(inputPath, sources, rf, pathJoin, extname4, basename4);
2860
+ await collectDir(inputPath, sources, rf, pathJoin, extname4, basename5);
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, basename4) {
2866
+ async function collectDir(dir, sources, rf, pathJoin, extname4, basename5) {
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, basename4);
2872
+ await collectDir(fullPath, sources, rf, pathJoin, extname4, basename5);
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 });
@@ -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: basename4 } = await import("path");
3560
+ const { basename: basename5 } = await import("path");
3561
3561
  write(`
3562
3562
  NeuroVerse World Builder
3563
3563
  `);
3564
3564
  write(`
3565
- Analyzing: ${basename4(args.inputPath)}
3565
+ Analyzing: ${basename5(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");
@@ -20473,17 +20473,30 @@ var init_think = __esm({
20473
20473
  });
20474
20474
 
20475
20475
  // src/radiant/core/scopes.ts
20476
- function parseRepoScope(scope) {
20476
+ function parseScope(scope) {
20477
20477
  const cleaned = scope.replace(/^https?:\/\//, "").replace(/^github\.com\//, "").replace(/\.git$/, "").replace(/\/$/, "");
20478
- const parts = cleaned.split("/");
20479
- if (parts.length < 2 || !parts[0] || !parts[1]) {
20478
+ const parts = cleaned.split("/").filter(Boolean);
20479
+ if (parts.length === 0 || !parts[0]) {
20480
+ throw new Error(
20481
+ `Cannot parse scope: "${scope}". Expected "owner/repo" or "owner".`
20482
+ );
20483
+ }
20484
+ if (parts.length === 1) {
20485
+ return { type: "org", owner: parts[0] };
20486
+ }
20487
+ return { type: "repo", owner: parts[0], repo: parts[1] };
20488
+ }
20489
+ function parseRepoScope(scope) {
20490
+ const parsed = parseScope(scope);
20491
+ if (parsed.type === "org") {
20480
20492
  throw new Error(
20481
- `Cannot parse repo scope: "${scope}". Expected "owner/repo" or a GitHub URL.`
20493
+ `Expected "owner/repo" but got org-level scope "${parsed.owner}". Use parseScope() for org-level.`
20482
20494
  );
20483
20495
  }
20484
- return { owner: parts[0], repo: parts[1] };
20496
+ return parsed;
20485
20497
  }
20486
20498
  function formatScope(scope) {
20499
+ if (scope.type === "org") return `${scope.owner} (org)`;
20487
20500
  return `${scope.owner}/${scope.repo}`;
20488
20501
  }
20489
20502
  var init_scopes = __esm({
@@ -20658,6 +20671,40 @@ async function fetchJSON(url, headers) {
20658
20671
  }
20659
20672
  return await res.json();
20660
20673
  }
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("/");
20695
+ 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);
20700
+ } catch {
20701
+ }
20702
+ }
20703
+ allEvents.sort(
20704
+ (a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
20705
+ );
20706
+ return { events: allEvents, repos: repoNames };
20707
+ }
20661
20708
  var KNOWN_AI_LOGINS, KNOWN_AI_CO_AUTHOR_NAMES;
20662
20709
  var init_github2 = __esm({
20663
20710
  "src/radiant/adapters/github.ts"() {
@@ -21372,6 +21419,14 @@ ${jargonTable}
21372
21419
 
21373
21420
  For example: don't say "update the worldmodel." Say "add a line to your strategy file."
21374
21421
 
21422
+ ## When the same invariant keeps firing
21423
+
21424
+ If the prior read history or the current evidence shows the same worldmodel invariant being triggered repeatedly (by the same side \u2014 human or AI), name it in MEANING and ask the real question:
21425
+
21426
+ "This invariant has been tested N times across M reads. Always on the [human/AI] side. Either the team needs alignment on WHY this rule exists \u2014 or the team is telling you something the worldmodel hasn't absorbed yet."
21427
+
21428
+ Don't just say "invariant held." Say what it means that people keep pushing against the same wall.
21429
+
21375
21430
  ## Health is a valid read
21376
21431
 
21377
21432
  If the activity is healthy and aligned with the worldmodel, SAY SO. Don't fabricate problems. Over-prescription is a voice failure. Legitimate outputs include:
@@ -21768,9 +21823,21 @@ async function emergent(input) {
21768
21823
  priorReadContext = formatPriorReadsForPrompt(priorReads);
21769
21824
  }
21770
21825
  }
21771
- const events = await fetchGitHubActivity(input.scope, input.githubToken, {
21772
- windowDays
21773
- });
21826
+ let events;
21827
+ let orgRepos;
21828
+ if (input.scope.type === "org") {
21829
+ const orgResult = await fetchGitHubOrgActivity(
21830
+ input.scope,
21831
+ input.githubToken,
21832
+ { windowDays }
21833
+ );
21834
+ events = orgResult.events;
21835
+ orgRepos = orgResult.repos;
21836
+ } else {
21837
+ events = await fetchGitHubActivity(input.scope, input.githubToken, {
21838
+ windowDays
21839
+ });
21840
+ }
21774
21841
  const classified = classifyEvents(events);
21775
21842
  const signals = extractSignals(classified);
21776
21843
  const scores = computeScores(signals, input.worldmodelContent !== "");
@@ -22220,6 +22287,8 @@ function parseArgs27(argv) {
22220
22287
  query: void 0,
22221
22288
  model: void 0,
22222
22289
  exocortex: void 0,
22290
+ teamExocortex: void 0,
22291
+ view: void 0,
22223
22292
  json: false,
22224
22293
  help: false,
22225
22294
  rest: []
@@ -22247,6 +22316,12 @@ function parseArgs27(argv) {
22247
22316
  case "--exocortex":
22248
22317
  result.exocortex = argv[++i];
22249
22318
  break;
22319
+ case "--team-exocortex":
22320
+ result.teamExocortex = argv[++i];
22321
+ break;
22322
+ case "--view":
22323
+ result.view = argv[++i];
22324
+ break;
22250
22325
  case "--json":
22251
22326
  result.json = true;
22252
22327
  break;
@@ -22388,7 +22463,7 @@ async function cmdEmergent(args) {
22388
22463
  );
22389
22464
  process.exit(1);
22390
22465
  }
22391
- const scope = parseRepoScope(scopeStr);
22466
+ const scope = parseScope(scopeStr);
22392
22467
  const lensId = args.lens ?? process.env.RADIANT_LENS;
22393
22468
  if (!lensId) {
22394
22469
  process.stderr.write(
@@ -22426,6 +22501,15 @@ ${DIM3}Set it to a GitHub PAT with repo read access.${RESET3}
22426
22501
  const worldmodelContent = loadWorldmodelContent2(worldsPath);
22427
22502
  const model = args.model ?? process.env.RADIANT_MODEL;
22428
22503
  const ai = createAnthropicAI(anthropicKey, model || void 0);
22504
+ const view = args.view ?? process.env.RADIANT_VIEW ?? "community";
22505
+ const validViews = ["community", "team", "full"];
22506
+ if (!validViews.includes(view)) {
22507
+ process.stderr.write(
22508
+ `${RED2}Error:${RESET3} --view must be community, team, or full. Got "${view}".
22509
+ `
22510
+ );
22511
+ process.exit(1);
22512
+ }
22429
22513
  const exocortexPath = args.exocortex ?? process.env.RADIANT_EXOCORTEX;
22430
22514
  let exocortexStatus = "not loaded";
22431
22515
  if (exocortexPath) {
@@ -22433,7 +22517,8 @@ ${DIM3}Set it to a GitHub PAT with repo read access.${RESET3}
22433
22517
  exocortexStatus = summarizeExocortex(ctx);
22434
22518
  }
22435
22519
  process.stderr.write(
22436
- `${DIM3}Scope: ${scope.owner}/${scope.repo}${RESET3}
22520
+ `${DIM3}Scope: ${scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo}${RESET3}
22521
+ ${DIM3}View: ${view}${RESET3}
22437
22522
  ${DIM3}Lens: ${lensId}${RESET3}
22438
22523
  ${DIM3}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET3}
22439
22524
  ${DIM3}ExoCortex: ${exocortexStatus}${RESET3}