@neuroverseos/governance 0.8.1 → 0.10.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.
@@ -20,6 +20,49 @@
20
20
  * RADIANT_WORLDS — default worlds directory (overridden by --worlds)
21
21
  * RADIANT_LENS — default lens id (overridden by --lens)
22
22
  */
23
+ interface ParsedArgs {
24
+ subcommand: string | undefined;
25
+ lens: string | undefined;
26
+ worlds: string | undefined;
27
+ query: string | undefined;
28
+ model: string | undefined;
29
+ exocortex: string | undefined;
30
+ teamExocortex: string | undefined;
31
+ view: string | undefined;
32
+ user: string | undefined;
33
+ personal: boolean;
34
+ entireOrg: boolean;
35
+ json: boolean;
36
+ help: boolean;
37
+ force: boolean;
38
+ rest: string[];
39
+ }
40
+ declare function parseArgs(argv: string[]): ParsedArgs;
41
+ interface ScopeConsentInput {
42
+ scope: {
43
+ type: 'org' | 'repo';
44
+ owner: string;
45
+ };
46
+ personal: boolean;
47
+ entireOrg: boolean;
48
+ resolvedUser: string | undefined;
49
+ }
50
+ type ScopeConsentResult = {
51
+ ok: true;
52
+ } | {
53
+ ok: false;
54
+ reason: 'personal_requires_user' | 'org_requires_opt_in';
55
+ };
56
+ /**
57
+ * Consent-first gate. Org-wide scopes observe every contributor across
58
+ * every repo — a global-observer stance that's opt-in, not the default.
59
+ * Personal mode requires a user to filter to.
60
+ *
61
+ * personal without user → reject (need --user or RADIANT_USER)
62
+ * org scope without --entire-org and without --personal → reject
63
+ * everything else → pass
64
+ */
65
+ declare function checkScopeConsent(input: ScopeConsentInput): ScopeConsentResult;
23
66
  declare function main(argv: string[]): Promise<void>;
24
67
 
25
- export { main };
68
+ export { type ScopeConsentInput, type ScopeConsentResult, checkScopeConsent, main, parseArgs };
@@ -20,6 +20,49 @@
20
20
  * RADIANT_WORLDS — default worlds directory (overridden by --worlds)
21
21
  * RADIANT_LENS — default lens id (overridden by --lens)
22
22
  */
23
+ interface ParsedArgs {
24
+ subcommand: string | undefined;
25
+ lens: string | undefined;
26
+ worlds: string | undefined;
27
+ query: string | undefined;
28
+ model: string | undefined;
29
+ exocortex: string | undefined;
30
+ teamExocortex: string | undefined;
31
+ view: string | undefined;
32
+ user: string | undefined;
33
+ personal: boolean;
34
+ entireOrg: boolean;
35
+ json: boolean;
36
+ help: boolean;
37
+ force: boolean;
38
+ rest: string[];
39
+ }
40
+ declare function parseArgs(argv: string[]): ParsedArgs;
41
+ interface ScopeConsentInput {
42
+ scope: {
43
+ type: 'org' | 'repo';
44
+ owner: string;
45
+ };
46
+ personal: boolean;
47
+ entireOrg: boolean;
48
+ resolvedUser: string | undefined;
49
+ }
50
+ type ScopeConsentResult = {
51
+ ok: true;
52
+ } | {
53
+ ok: false;
54
+ reason: 'personal_requires_user' | 'org_requires_opt_in';
55
+ };
56
+ /**
57
+ * Consent-first gate. Org-wide scopes observe every contributor across
58
+ * every repo — a global-observer stance that's opt-in, not the default.
59
+ * Personal mode requires a user to filter to.
60
+ *
61
+ * personal without user → reject (need --user or RADIANT_USER)
62
+ * org scope without --entire-org and without --personal → reject
63
+ * everything else → pass
64
+ */
65
+ declare function checkScopeConsent(input: ScopeConsentInput): ScopeConsentResult;
23
66
  declare function main(argv: string[]): Promise<void>;
24
67
 
25
- export { main };
68
+ export { type ScopeConsentInput, type ScopeConsentResult, checkScopeConsent, main, parseArgs };
@@ -1,23 +1,26 @@
1
1
  import {
2
2
  createAnthropicAI,
3
+ discoverWorlds,
3
4
  emergent,
5
+ formatActiveWorlds,
4
6
  parseScope,
5
7
  readExocortex,
6
8
  summarizeExocortex,
7
9
  think
8
- } from "../chunk-ETDIEVAX.js";
10
+ } from "../chunk-BZYQHJDM.js";
9
11
  import {
10
12
  listLenses
11
- } from "../chunk-F2LWMOM5.js";
13
+ } from "../chunk-TCGGED4G.js";
12
14
  import "../chunk-I4RTIMLX.js";
13
15
  import "../chunk-ZAF6JH23.js";
14
16
  import "../chunk-QLPTHTVB.js";
15
17
  import "../chunk-QWGCMQQD.js";
16
18
 
17
19
  // src/cli/radiant.ts
18
- import { readFileSync, readdirSync, statSync, existsSync } from "fs";
20
+ import { readFileSync, readdirSync, statSync, existsSync, mkdirSync, writeFileSync } from "fs";
19
21
  import { resolve, join, extname } from "path";
20
22
  var RED = "\x1B[31m";
23
+ var GREEN = "\x1B[32m";
21
24
  var DIM = "\x1B[2m";
22
25
  var BOLD = "\x1B[1m";
23
26
  var YELLOW = "\x1B[33m";
@@ -25,6 +28,9 @@ var RESET = "\x1B[0m";
25
28
  var USAGE = `
26
29
  ${BOLD}neuroverse radiant${RESET} \u2014 behavioral intelligence for collaboration systems
27
30
 
31
+ ${BOLD}Setup:${RESET}
32
+ init Scaffold a Mind Palace in the current directory
33
+
28
34
  ${BOLD}Stage A (voice layer):${RESET}
29
35
  think Send a query through the worldmodel + lens \u2192 AI-framed response
30
36
 
@@ -35,19 +41,46 @@ ${BOLD}Stage B (behavioral analysis, coming soon):${RESET}
35
41
  lenses List or describe available rendering lenses
36
42
 
37
43
  ${BOLD}Usage:${RESET}
44
+ neuroverse radiant init (scaffolds ./mind-palace/)
45
+ neuroverse radiant init ./my-palace (custom path)
38
46
  neuroverse radiant think --lens auki-builder --worlds ./worlds/ --query "What is our biggest risk?"
39
47
  neuroverse radiant think --lens auki-builder --worlds ./worlds/ < prompt.txt
40
48
  neuroverse radiant emergent aukiverse/posemesh --lens auki-builder --worlds ./worlds/
41
49
  neuroverse radiant emergent aukiverse/posemesh --lens auki-builder --worlds ./worlds/ --exocortex ~/exocortex/
50
+ neuroverse radiant emergent aukilabs/posemesh --personal --user alice
51
+ neuroverse radiant emergent aukilabs/ --entire-org --lens auki-builder --worlds ./worlds/
42
52
  neuroverse radiant lenses list
43
53
  neuroverse radiant lenses describe auki-builder
44
54
 
55
+ ${BOLD}Read modes:${RESET}
56
+ ${BOLD}Default (team):${RESET} reads all contributors in the given scope.
57
+ ${BOLD}--personal --user <login>:${RESET} reads ONLY that user's activity.
58
+ A local, private facilitator \u2014 no one else is observed. Works against
59
+ any scope; an org scope with --personal is fine.
60
+ ${BOLD}--entire-org (gated):${RESET} org-wide scope observes every contributor
61
+ across every repo. This is a global-observer stance and is opt-in.
62
+ \`radiant emergent <org>/\` without --entire-org will refuse and show
63
+ you the three choices (single repo, --personal, or explicit opt-in).
64
+
65
+ ${BOLD}Auto-discovery:${RESET}
66
+ You do not need to clone the target repo.
67
+
68
+ radiant emergent NeuroverseOS/ \u2192 probes github.com/NeuroverseOS/worlds
69
+ radiant emergent aukiverse/posemesh \u2192 probes github.com/aukiverse/worlds
70
+
71
+ The scope argument itself is enough. Discovery also picks up
72
+ ~/.neuroverse/worlds/ (personal), the org from your current clone's
73
+ .git/config (if any), and ./worlds/ (this repo).
74
+
75
+ Set NEUROVERSE_NO_ORG=1 to disable org probing for a single run.
76
+
45
77
  ${BOLD}Environment:${RESET}
46
78
  ANTHROPIC_API_KEY Required for AI commands (think, emergent, decision)
47
79
  RADIANT_WORLDS Default worlds directory (overridden by --worlds)
48
80
  RADIANT_LENS Default lens id (overridden by --lens)
49
81
  RADIANT_MODEL AI model override (default: claude-sonnet-4-20250514)
50
82
  RADIANT_EXOCORTEX Default exocortex directory (overridden by --exocortex)
83
+ RADIANT_USER Default personal-mode user (overridden by --user)
51
84
  `.trim();
52
85
  function parseArgs(argv) {
53
86
  const result = {
@@ -59,8 +92,12 @@ function parseArgs(argv) {
59
92
  exocortex: void 0,
60
93
  teamExocortex: void 0,
61
94
  view: void 0,
95
+ user: void 0,
96
+ personal: false,
97
+ entireOrg: false,
62
98
  json: false,
63
99
  help: false,
100
+ force: false,
64
101
  rest: []
65
102
  };
66
103
  let i = 0;
@@ -92,9 +129,22 @@ function parseArgs(argv) {
92
129
  case "--view":
93
130
  result.view = argv[++i];
94
131
  break;
132
+ case "--user":
133
+ result.user = argv[++i];
134
+ break;
135
+ case "--personal":
136
+ result.personal = true;
137
+ break;
138
+ case "--entire-org":
139
+ result.entireOrg = true;
140
+ break;
95
141
  case "--json":
96
142
  result.json = true;
97
143
  break;
144
+ case "--force":
145
+ case "-f":
146
+ result.force = true;
147
+ break;
98
148
  case "--help":
99
149
  case "-h":
100
150
  result.help = true;
@@ -133,20 +183,48 @@ ${content}`;
133
183
  }
134
184
  throw new Error(`Worlds path is neither a file nor a directory: ${resolved}`);
135
185
  }
136
- async function cmdThink(args) {
137
- const lensId = args.lens ?? process.env.RADIANT_LENS;
138
- if (!lensId) {
186
+ function resolveWorldmodelContent(explicitPath, scopeOwner) {
187
+ if (explicitPath) {
188
+ return loadWorldmodelContent(explicitPath);
189
+ }
190
+ const stack = discoverWorlds({
191
+ repoDir: process.cwd(),
192
+ scopeOwner
193
+ });
194
+ if (stack.worlds.length === 0) {
195
+ const scopeLine = scopeOwner ? ` 3. github:${scopeOwner}/worlds (from scope arg)
196
+ ` : "";
197
+ const ext = scopeOwner ? 4 : 3;
198
+ const repo = scopeOwner ? 5 : 4;
139
199
  process.stderr.write(
140
- `${RED}Error:${RESET} --lens <id> or RADIANT_LENS required.
141
- ${DIM}Available lenses: ${listLenses().join(", ")}${RESET}
200
+ `${RED}Error:${RESET} No worldmodel found.
201
+ ${DIM}Tried (in order):
202
+ 1. ~/.neuroverse/worlds/ (user tier)
203
+ 2. github:<owner>/worlds (org auto-detect from git remote)
204
+ ` + scopeLine + ` ${ext}. .neuroverse/config.json extends (explicit shared worlds)
205
+ ${repo}. ./worlds/ or ./.neuroverse/worlds/ (repo tier)
206
+
207
+ Pass --worlds <dir> or set RADIANT_WORLDS to specify explicitly.
208
+ Or run against a <scope>/ where github.com/<scope>/worlds exists.${RESET}
142
209
  `
143
210
  );
144
211
  process.exit(1);
145
212
  }
146
- const worldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
147
- if (!worldsPath) {
213
+ process.stderr.write(`${DIM}${formatActiveWorlds(stack)}${RESET}
214
+
215
+ `);
216
+ for (const warning of stack.warnings) {
217
+ process.stderr.write(`${YELLOW}\u26A0${RESET} ${warning}
218
+ `);
219
+ }
220
+ return stack.combinedContent;
221
+ }
222
+ async function cmdThink(args) {
223
+ const lensId = args.lens ?? process.env.RADIANT_LENS;
224
+ if (!lensId) {
148
225
  process.stderr.write(
149
- `${RED}Error:${RESET} --worlds <dir> or RADIANT_WORLDS required.
226
+ `${RED}Error:${RESET} --lens <id> or RADIANT_LENS required.
227
+ ${DIM}Available lenses: ${listLenses().join(", ")}${RESET}
150
228
  `
151
229
  );
152
230
  process.exit(1);
@@ -175,12 +253,12 @@ ${DIM}Use --query "...", pass as trailing args, or pipe via stdin.${RESET}
175
253
  );
176
254
  process.exit(1);
177
255
  }
178
- const worldmodelContent = loadWorldmodelContent(worldsPath);
256
+ const explicitWorldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
257
+ const worldmodelContent = resolveWorldmodelContent(explicitWorldsPath);
179
258
  const model = args.model ?? process.env.RADIANT_MODEL;
180
259
  const ai = createAnthropicAI(apiKey, model || void 0);
181
260
  process.stderr.write(
182
- `${DIM}Worlds: ${worldsPath}${RESET}
183
- ${DIM}Lens: ${lensId}${RESET}
261
+ `${DIM}Lens: ${lensId}${RESET}
184
262
  ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
185
263
 
186
264
  `
@@ -224,6 +302,15 @@ ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
224
302
  process.exit(2);
225
303
  }
226
304
  }
305
+ function checkScopeConsent(input) {
306
+ if (input.personal && !input.resolvedUser) {
307
+ return { ok: false, reason: "personal_requires_user" };
308
+ }
309
+ if (input.scope.type === "org" && !input.entireOrg && !input.personal) {
310
+ return { ok: false, reason: "org_requires_opt_in" };
311
+ }
312
+ return { ok: true };
313
+ }
227
314
  async function cmdEmergent(args) {
228
315
  const scopeStr = args.rest[0];
229
316
  if (!scopeStr) {
@@ -234,19 +321,48 @@ async function cmdEmergent(args) {
234
321
  process.exit(1);
235
322
  }
236
323
  const scope = parseScope(scopeStr);
324
+ const personalUser = args.user ?? process.env.RADIANT_USER;
325
+ const consent = checkScopeConsent({
326
+ scope,
327
+ personal: args.personal,
328
+ entireOrg: args.entireOrg,
329
+ resolvedUser: personalUser
330
+ });
331
+ if (!consent.ok) {
332
+ if (consent.reason === "personal_requires_user") {
333
+ process.stderr.write(
334
+ `${RED}Error:${RESET} --personal requires a GitHub username.
335
+ ${DIM}Pass --user <login> or set RADIANT_USER. Radiant will read
336
+ only that user's activity \u2014 no one else is observed.${RESET}
337
+ `
338
+ );
339
+ } else {
340
+ process.stderr.write(
341
+ `${YELLOW}\u26A0${RESET} ${BOLD}"${scope.owner}" is an org-wide scope.${RESET}
342
+
343
+ ${DIM}This reads activity across ALL repos in the org \u2014 a global-observer
344
+ pattern that some teams consider offside with decentralization and
345
+ cognitive-liberty principles. It's opt-in for that reason.${RESET}
346
+
347
+ Three ways forward:
348
+ ${GREEN}1.${RESET} Scope to a single repo (recommended default):
349
+ radiant emergent ${scope.owner}/<repo>
350
+
351
+ ${GREEN}2.${RESET} Read only your own activity (personal mode):
352
+ radiant emergent ${scope.owner}/ --personal --user <your-login>
353
+
354
+ ${GREEN}3.${RESET} Explicitly opt in to org-wide observation:
355
+ radiant emergent ${scope.owner}/ --entire-org
356
+ `
357
+ );
358
+ }
359
+ process.exit(1);
360
+ }
237
361
  const lensId = args.lens ?? process.env.RADIANT_LENS;
238
362
  if (!lensId) {
239
363
  process.stderr.write(
240
364
  `${RED}Error:${RESET} --lens <id> or RADIANT_LENS required.
241
365
  ${DIM}Available lenses: ${listLenses().join(", ")}${RESET}
242
- `
243
- );
244
- process.exit(1);
245
- }
246
- const worldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
247
- if (!worldsPath) {
248
- process.stderr.write(
249
- `${RED}Error:${RESET} --worlds <dir> or RADIANT_WORLDS required.
250
366
  `
251
367
  );
252
368
  process.exit(1);
@@ -268,7 +384,11 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
268
384
  );
269
385
  process.exit(1);
270
386
  }
271
- const worldmodelContent = loadWorldmodelContent(worldsPath);
387
+ const explicitWorldsPath = args.worlds ?? process.env.RADIANT_WORLDS;
388
+ const worldmodelContent = resolveWorldmodelContent(
389
+ explicitWorldsPath,
390
+ scope.owner
391
+ );
272
392
  const model = args.model ?? process.env.RADIANT_MODEL;
273
393
  const ai = createAnthropicAI(anthropicKey, model || void 0);
274
394
  const view = args.view ?? process.env.RADIANT_VIEW ?? "community";
@@ -286,8 +406,11 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
286
406
  const ctx = readExocortex(exocortexPath);
287
407
  exocortexStatus = summarizeExocortex(ctx);
288
408
  }
409
+ const scopeLabel = scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo;
410
+ const modeLabel = args.personal ? `personal \u2014 only ${personalUser}'s activity` : "team \u2014 all contributors";
289
411
  process.stderr.write(
290
- `${DIM}Scope: ${scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo}${RESET}
412
+ `${DIM}Scope: ${scopeLabel}${RESET}
413
+ ${DIM}Mode: ${modeLabel}${RESET}
291
414
  ${DIM}View: ${view}${RESET}
292
415
  ${DIM}Lens: ${lensId}${RESET}
293
416
  ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
@@ -303,7 +426,8 @@ ${DIM}Fetching activity...${RESET}
303
426
  lensId,
304
427
  ai,
305
428
  windowDays: 14,
306
- exocortexPath: exocortexPath || void 0
429
+ exocortexPath: exocortexPath || void 0,
430
+ personalUser: args.personal ? personalUser : void 0
307
431
  });
308
432
  if (!result.voiceClean) {
309
433
  process.stderr.write(
@@ -351,7 +475,7 @@ async function cmdLenses(args) {
351
475
  return;
352
476
  }
353
477
  if (subSub === "describe") {
354
- const { getLens } = await import("../lenses-YDMKSXDL.js");
478
+ const { getLens } = await import("../lenses-XDWK6ZKI.js");
355
479
  const id = args.rest[1];
356
480
  if (!id) {
357
481
  process.stderr.write(`${RED}Error:${RESET} Lens id required.
@@ -405,6 +529,204 @@ ${DIM}Use: lenses list | lenses describe <id>${RESET}
405
529
  );
406
530
  process.exit(1);
407
531
  }
532
+ var MIND_PALACE_FILES = {
533
+ "README.md": `# Mind Palace
534
+
535
+ This is your Mind Palace \u2014 structured external memory that gives Radiant
536
+ (and any agent you wire into it) persistent context about who you are,
537
+ what you're working on, and what "on track" means for you.
538
+
539
+ Radiant reads these files before every run and writes each read back into
540
+ \`reads/\`. Over time, \`knowledge.md\` accumulates what's persisted and what
541
+ hasn't \u2014 the feedback loop that turns raw activity into named behavior.
542
+
543
+ ## Files
544
+
545
+ - \`attention.md\` \u2014 what you're focused on **right now**
546
+ - \`goals.md\` \u2014 what you're working toward
547
+ - \`sprint.md\` \u2014 this week's focus
548
+ - \`identity.md\` \u2014 who you are, what you value
549
+ - \`worldmodels/\` \u2014 your thinking constitutions (drift + aligned behaviors)
550
+ - \`reads/\` \u2014 dated Radiant reads (written by \`radiant emergent\`)
551
+ - \`knowledge.md\` \u2014 accumulated pattern persistence across reads
552
+
553
+ ## How to use
554
+
555
+ 1. Fill in \`attention.md\`, \`goals.md\`, \`sprint.md\`, \`identity.md\` with
556
+ your own words. A sentence each is enough to start \u2014 the files grow
557
+ with you.
558
+ 2. Edit \`worldmodels/starter.worldmodel.md\`: add a few aligned behaviors
559
+ (what on-track looks like) and drift behaviors (what off-track looks
560
+ like). The sharper these are, the sharper Radiant's reads.
561
+ 3. Run \`neuroverse radiant emergent <owner/repo> --mind-palace .\` against
562
+ the repo you want read. Radiant compares your stated intent (these
563
+ files) to your observed activity (GitHub) and names the gap.
564
+
565
+ Edit freely. These files are yours.
566
+ `,
567
+ "attention.md": `# Attention
568
+
569
+ <!--
570
+ What are you focused on RIGHT NOW? One paragraph. Updated as you shift.
571
+ This is the file an AI agent reads at the start of a session to know
572
+ what to help with today.
573
+ -->
574
+
575
+ `,
576
+ "goals.md": `# Goals
577
+
578
+ <!--
579
+ What are you working toward? Bullet points welcome.
580
+ Longer horizon than attention \u2014 months, not days.
581
+ -->
582
+
583
+ -
584
+ `,
585
+ "sprint.md": `# Sprint
586
+
587
+ <!--
588
+ This week's focus. What do you want to ship or finish?
589
+ Keep it short \u2014 five bullets max.
590
+ -->
591
+
592
+ -
593
+ `,
594
+ "identity.md": `# Identity
595
+
596
+ <!--
597
+ Who are you, what do you value, how do you work?
598
+ This is the context an agent needs to not treat you like a stranger
599
+ every time. Write it in your own voice.
600
+ -->
601
+
602
+ `,
603
+ "knowledge.md": `# Knowledge
604
+
605
+ <!--
606
+ Radiant writes accumulated pattern persistence here across reads.
607
+ Leave this file empty on day one \u2014 it fills up as \`radiant emergent\`
608
+ runs accumulate.
609
+ -->
610
+
611
+ `,
612
+ "reads/.gitkeep": "",
613
+ "worldmodels/starter.worldmodel.md": `# Starter Worldmodel
614
+
615
+ <!--
616
+ Your thinking constitution. Radiant reads this to understand what
617
+ "aligned" and "drift" mean for your work.
618
+
619
+ The sharper the Aligned/Drift Behaviors, the sharper Radiant's reads.
620
+ When Radiant detects something matching a drift behavior below, it
621
+ labels it with THAT name \u2014 it doesn't invent new ones.
622
+ -->
623
+
624
+ ## Mission
625
+
626
+ <!-- One sentence. What are you doing in the world? -->
627
+
628
+
629
+ ## Invariants
630
+
631
+ <!--
632
+ Non-negotiable rules. If a decision violates one, it's blocked.
633
+ Keep this list short \u2014 3 to 6 items. Each should be a hard no.
634
+ -->
635
+
636
+ -
637
+
638
+ ## Aligned Behaviors
639
+
640
+ <!--
641
+ What "on track" looks like. One per line, phrased as a behavior.
642
+ Radiant will use these as canonical pattern names when it sees
643
+ matching evidence in your activity.
644
+
645
+ Example:
646
+ - ships partial-but-working features rather than waiting for the full stack
647
+ - writes decisions down before acting on them
648
+ -->
649
+
650
+ -
651
+
652
+ ## Drift Behaviors
653
+
654
+ <!--
655
+ What "off track" looks like. Same format as Aligned.
656
+ When Radiant detects drift, it will label it with these names \u2014 not
657
+ make up new ones.
658
+
659
+ Example:
660
+ - shipping pace outruns strategic decision-making
661
+ - architecture decisions surface without context about why
662
+ -->
663
+
664
+ -
665
+
666
+ ## Signals
667
+
668
+ <!--
669
+ Observable quantities you care about. Radiant scores activity
670
+ against these \u2014 5 to 7 is the sweet spot.
671
+
672
+ Example:
673
+ - shipping_velocity
674
+ - decision_ownership
675
+ - storytelling_cadence
676
+ -->
677
+
678
+ -
679
+
680
+ ## Decision Priorities
681
+
682
+ <!--
683
+ When tradeoffs appear, these resolve them. Format: "A > B".
684
+
685
+ Example:
686
+ - correctness > speed
687
+ - clarity > cleverness
688
+ -->
689
+
690
+ -
691
+ `
692
+ };
693
+ async function cmdInit(args) {
694
+ const targetDir = resolve(args.rest[0] ?? "./mind-palace");
695
+ const existed = existsSync(targetDir);
696
+ if (existed && !args.force) {
697
+ const entries = readdirSync(targetDir);
698
+ if (entries.length > 0) {
699
+ process.stderr.write(
700
+ `${RED}Error:${RESET} ${targetDir} already exists and is not empty.
701
+ ${DIM}Use --force to write into it anyway (existing files will be overwritten).${RESET}
702
+ `
703
+ );
704
+ process.exit(1);
705
+ }
706
+ }
707
+ mkdirSync(targetDir, { recursive: true });
708
+ mkdirSync(join(targetDir, "reads"), { recursive: true });
709
+ mkdirSync(join(targetDir, "worldmodels"), { recursive: true });
710
+ for (const [relPath, content] of Object.entries(MIND_PALACE_FILES)) {
711
+ const fullPath = join(targetDir, relPath);
712
+ mkdirSync(resolve(fullPath, ".."), { recursive: true });
713
+ writeFileSync(fullPath, content, "utf-8");
714
+ }
715
+ process.stdout.write(
716
+ `${GREEN}\u2713${RESET} Mind Palace scaffolded at ${BOLD}${targetDir}${RESET}
717
+
718
+ ${DIM}Next steps:${RESET}
719
+ 1. Edit ${targetDir}/attention.md \u2014 what you're focused on right now
720
+ 2. Edit ${targetDir}/worldmodels/starter.worldmodel.md \u2014 add a few
721
+ aligned and drift behaviors
722
+ 3. Run: neuroverse radiant emergent <owner/repo> \\
723
+ --worlds ${targetDir}/worldmodels \\
724
+ --exocortex ${targetDir}
725
+
726
+ ${DIM}Files are yours. Edit freely.${RESET}
727
+ `
728
+ );
729
+ }
408
730
  async function main(argv) {
409
731
  const args = parseArgs(argv);
410
732
  if (args.help || !args.subcommand) {
@@ -412,6 +734,8 @@ async function main(argv) {
412
734
  return;
413
735
  }
414
736
  switch (args.subcommand) {
737
+ case "init":
738
+ return cmdInit(args);
415
739
  case "think":
416
740
  return cmdThink(args);
417
741
  case "lenses":
@@ -419,7 +743,7 @@ async function main(argv) {
419
743
  case "emergent":
420
744
  return cmdEmergent(args);
421
745
  case "mcp": {
422
- const { startRadiantMcp } = await import("../server-ZSQ6DRSN.js");
746
+ const { startRadiantMcp } = await import("../server-EI5JCIBU.js");
423
747
  return startRadiantMcp(argv);
424
748
  }
425
749
  case "decision":
@@ -443,5 +767,7 @@ async function main(argv) {
443
767
  }
444
768
  }
445
769
  export {
446
- main
770
+ checkScopeConsent,
771
+ main,
772
+ parseArgs
447
773
  };