@neuroverseos/governance 0.7.0 → 0.8.1

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.
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  createAnthropicAI,
3
3
  emergent,
4
- parseRepoScope,
4
+ parseScope,
5
5
  readExocortex,
6
6
  summarizeExocortex,
7
7
  think
8
- } from "../chunk-T6EQ7ZBG.js";
8
+ } from "../chunk-ETDIEVAX.js";
9
9
  import {
10
10
  listLenses
11
- } from "../chunk-VGFDMPVB.js";
11
+ } from "../chunk-F2LWMOM5.js";
12
12
  import "../chunk-I4RTIMLX.js";
13
13
  import "../chunk-ZAF6JH23.js";
14
14
  import "../chunk-QLPTHTVB.js";
@@ -57,6 +57,8 @@ function parseArgs(argv) {
57
57
  query: void 0,
58
58
  model: void 0,
59
59
  exocortex: void 0,
60
+ teamExocortex: void 0,
61
+ view: void 0,
60
62
  json: false,
61
63
  help: false,
62
64
  rest: []
@@ -84,6 +86,12 @@ function parseArgs(argv) {
84
86
  case "--exocortex":
85
87
  result.exocortex = argv[++i];
86
88
  break;
89
+ case "--team-exocortex":
90
+ result.teamExocortex = argv[++i];
91
+ break;
92
+ case "--view":
93
+ result.view = argv[++i];
94
+ break;
87
95
  case "--json":
88
96
  result.json = true;
89
97
  break;
@@ -225,7 +233,7 @@ async function cmdEmergent(args) {
225
233
  );
226
234
  process.exit(1);
227
235
  }
228
- const scope = parseRepoScope(scopeStr);
236
+ const scope = parseScope(scopeStr);
229
237
  const lensId = args.lens ?? process.env.RADIANT_LENS;
230
238
  if (!lensId) {
231
239
  process.stderr.write(
@@ -263,6 +271,15 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
263
271
  const worldmodelContent = loadWorldmodelContent(worldsPath);
264
272
  const model = args.model ?? process.env.RADIANT_MODEL;
265
273
  const ai = createAnthropicAI(anthropicKey, model || void 0);
274
+ const view = args.view ?? process.env.RADIANT_VIEW ?? "community";
275
+ const validViews = ["community", "team", "full"];
276
+ if (!validViews.includes(view)) {
277
+ process.stderr.write(
278
+ `${RED}Error:${RESET} --view must be community, team, or full. Got "${view}".
279
+ `
280
+ );
281
+ process.exit(1);
282
+ }
266
283
  const exocortexPath = args.exocortex ?? process.env.RADIANT_EXOCORTEX;
267
284
  let exocortexStatus = "not loaded";
268
285
  if (exocortexPath) {
@@ -270,7 +287,8 @@ ${DIM}Set it to a GitHub PAT with repo read access.${RESET}
270
287
  exocortexStatus = summarizeExocortex(ctx);
271
288
  }
272
289
  process.stderr.write(
273
- `${DIM}Scope: ${scope.owner}/${scope.repo}${RESET}
290
+ `${DIM}Scope: ${scope.type === "org" ? scope.owner + " (entire org)" : scope.owner + "/" + scope.repo}${RESET}
291
+ ${DIM}View: ${view}${RESET}
274
292
  ${DIM}Lens: ${lensId}${RESET}
275
293
  ${DIM}Model: ${model ?? "claude-sonnet-4-20250514 (default)"}${RESET}
276
294
  ${DIM}ExoCortex: ${exocortexStatus}${RESET}
@@ -333,7 +351,7 @@ async function cmdLenses(args) {
333
351
  return;
334
352
  }
335
353
  if (subSub === "describe") {
336
- const { getLens } = await import("../lenses-K5FVSALR.js");
354
+ const { getLens } = await import("../lenses-YDMKSXDL.js");
337
355
  const id = args.rest[1];
338
356
  if (!id) {
339
357
  process.stderr.write(`${RED}Error:${RESET} Lens id required.
@@ -401,7 +419,7 @@ async function main(argv) {
401
419
  case "emergent":
402
420
  return cmdEmergent(args);
403
421
  case "mcp": {
404
- const { startRadiantMcp } = await import("../server-BXMC5NOE.js");
422
+ const { startRadiantMcp } = await import("../server-ZSQ6DRSN.js");
405
423
  return startRadiantMcp(argv);
406
424
  }
407
425
  case "decision":
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -17,6 +20,207 @@ var __copyProps = (to, from, except, desc) => {
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
22
 
23
+ // src/cli/worldmodel-create.ts
24
+ var worldmodel_create_exports = {};
25
+ __export(worldmodel_create_exports, {
26
+ askQuestions: () => askQuestions,
27
+ saveWorldmodel: () => saveWorldmodel,
28
+ structureWorldmodel: () => structureWorldmodel
29
+ });
30
+ async function askQuestions() {
31
+ const rl = (0, import_readline.createInterface)({
32
+ input: process.stdin,
33
+ output: process.stderr
34
+ // questions to stderr so stdout stays clean
35
+ });
36
+ const answers = {};
37
+ process.stderr.write("\n");
38
+ 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");
39
+ process.stderr.write(" \u2551 NeuroVerseOS \u2014 Build your thinking constitution \u2551\n");
40
+ 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");
41
+ process.stderr.write("\n");
42
+ process.stderr.write(" Answer these questions in your own words.\n");
43
+ process.stderr.write(" There are no wrong answers \u2014 just say what you mean.\n");
44
+ process.stderr.write(" The AI will structure your answers into a worldmodel.\n\n");
45
+ for (const q of QUESTIONS) {
46
+ const answer = await new Promise((resolve3) => {
47
+ process.stderr.write(` \x1B[1m${q.question}\x1B[0m
48
+ `);
49
+ process.stderr.write(` \x1B[2m${q.placeholder}\x1B[0m
50
+ `);
51
+ rl.question(" > ", (ans) => {
52
+ process.stderr.write("\n");
53
+ resolve3(ans.trim());
54
+ });
55
+ });
56
+ answers[q.id] = answer;
57
+ }
58
+ rl.close();
59
+ return answers;
60
+ }
61
+ async function structureWorldmodel(answers, apiKey) {
62
+ const prompt = buildStructuringPrompt(answers);
63
+ const res = await fetch("https://api.anthropic.com/v1/messages", {
64
+ method: "POST",
65
+ headers: {
66
+ "x-api-key": apiKey,
67
+ "anthropic-version": "2023-06-01",
68
+ "content-type": "application/json"
69
+ },
70
+ body: JSON.stringify({
71
+ model: "claude-sonnet-4-20250514",
72
+ max_tokens: 4096,
73
+ 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.",
74
+ messages: [{ role: "user", content: prompt }]
75
+ })
76
+ });
77
+ if (!res.ok) {
78
+ throw new Error(`AI structuring failed: ${res.status}`);
79
+ }
80
+ const data = await res.json();
81
+ const text = data.content?.filter((c) => c.type === "text").map((c) => c.text ?? "").join("");
82
+ if (!text) throw new Error("AI returned no content");
83
+ return text.replace(/^```markdown\n?/, "").replace(/\n?```$/, "").trim();
84
+ }
85
+ function buildStructuringPrompt(answers) {
86
+ return `Structure these conversational answers into a .worldmodel.md file.
87
+
88
+ The file MUST follow this exact three-layer format:
89
+
90
+ ---
91
+ name: ${answers.name}
92
+ version: 1.0.0
93
+ ---
94
+
95
+ # Core Model Geometry
96
+
97
+ ## Mission
98
+ (from the mission answer)
99
+
100
+ ## Domains
101
+ (2-4 domains from the domains answer, each with:)
102
+ ### Domain Name
103
+ #### Skills (8-10 skills per domain, inferred from the answers)
104
+ #### Values (3-4 values per domain, drawn from the non-negotiables + mission)
105
+
106
+ ## Overlap Effects
107
+ (from the overlaps answer, formatted as: Domain A + Domain B = Emergent State)
108
+
109
+ ## Center Identity
110
+ (from the center answer)
111
+
112
+ # Contextual Modifiers
113
+
114
+ ## Authority Layers
115
+ (infer 4-5 authority levels appropriate to this organization)
116
+
117
+ ## Spatial Contexts
118
+ (infer 4-5 contexts where behavior happens)
119
+
120
+ ## Interpretation Rules
121
+ (infer 3-5 rules about how context changes meaning)
122
+
123
+ # Evolution Layer
124
+
125
+ ## Aligned Behaviors
126
+ (from the success answer, expanded to 5-8 items)
127
+
128
+ ## Drift Behaviors
129
+ (from the drift answer, expanded to 5-8 items)
130
+
131
+ ## Signals
132
+ (infer 5-7 observable signals from the answers, snake_case)
133
+
134
+ ## Decision Priorities
135
+ (from the priorities answer, formatted as: preferred > secondary)
136
+
137
+ ## Evolution Conditions
138
+ (infer 3-5 conditions for when the model should adapt)
139
+
140
+ HERE ARE THE ANSWERS:
141
+
142
+ Name: ${answers.name}
143
+
144
+ Mission: ${answers.mission}
145
+
146
+ Domains: ${answers.domains}
147
+
148
+ Overlaps: ${answers.overlaps}
149
+
150
+ Center identity: ${answers.center}
151
+
152
+ Non-negotiables: ${answers.nonnegotiables}
153
+
154
+ Success looks like: ${answers.success}
155
+
156
+ Drift looks like: ${answers.drift}
157
+
158
+ Priorities: ${answers.priorities}
159
+
160
+ Output ONLY the .worldmodel.md content. No explanation. No commentary. Just the file.`;
161
+ }
162
+ function saveWorldmodel(content, outputPath) {
163
+ const resolved = (0, import_path.resolve)(outputPath);
164
+ (0, import_fs.writeFileSync)(resolved, content, "utf-8");
165
+ return resolved;
166
+ }
167
+ var import_readline, import_fs, import_path, QUESTIONS;
168
+ var init_worldmodel_create = __esm({
169
+ "src/cli/worldmodel-create.ts"() {
170
+ "use strict";
171
+ import_readline = require("readline");
172
+ import_fs = require("fs");
173
+ import_path = require("path");
174
+ QUESTIONS = [
175
+ {
176
+ id: "name",
177
+ question: "What should we call this model? (Your name, your org, your project)",
178
+ placeholder: 'e.g., "Kirsten", "Auki", "My Startup"'
179
+ },
180
+ {
181
+ id: "mission",
182
+ question: "In one or two sentences \u2014 what does this system exist to do? Not a slogan. The real purpose.",
183
+ placeholder: 'e.g., "Protect human thinking while expanding cognitive capability through AI"'
184
+ },
185
+ {
186
+ id: "domains",
187
+ question: "What are the 2-3 big areas of focus? Not departments \u2014 the major kinds of work that matter most. Separate with commas.",
188
+ placeholder: 'e.g., "Safety and boundaries, Individual authority, AI as cognitive extension"'
189
+ },
190
+ {
191
+ id: "overlaps",
192
+ question: "When those areas work well TOGETHER, what does that feel like? Name a feeling for each pair.",
193
+ placeholder: 'e.g., "Safety + Authority = Trust, Authority + AI = Possibility"'
194
+ },
195
+ {
196
+ id: "center",
197
+ question: "When EVERYTHING is aligned \u2014 all areas working together \u2014 what does the system become? One name or phrase.",
198
+ placeholder: 'e.g., "The Sovereign Conduit", "Collective Vanguard Leader"'
199
+ },
200
+ {
201
+ id: "nonnegotiables",
202
+ question: "What's absolutely non-negotiable? What would you walk away over? List a few.",
203
+ placeholder: 'e.g., "Humans retain authority over thinking. AI extends, never replaces. People can always leave."'
204
+ },
205
+ {
206
+ id: "success",
207
+ question: `What does success look like in action? What would you point at and say "that's what I mean"?`,
208
+ placeholder: 'e.g., "Someone maintaining clear authorship of decisions even when AI contributed"'
209
+ },
210
+ {
211
+ id: "drift",
212
+ question: "What does drift look like? What would worry you if you saw it happening?",
213
+ placeholder: 'e.g., "Decision ownership quietly shifting to AI without explicit delegation"'
214
+ },
215
+ {
216
+ id: "priorities",
217
+ question: 'When tradeoffs appear, what wins? Give a few "X over Y" pairs.',
218
+ placeholder: 'e.g., "Safety over speed, sovereignty over convenience, diversity over uniformity"'
219
+ }
220
+ ];
221
+ }
222
+ });
223
+
20
224
  // src/cli/worldmodel.ts
21
225
  var worldmodel_exports = {};
22
226
  __export(worldmodel_exports, {
@@ -24,8 +228,8 @@ __export(worldmodel_exports, {
24
228
  });
25
229
  module.exports = __toCommonJS(worldmodel_exports);
26
230
  var import_promises = require("fs/promises");
27
- var import_fs = require("fs");
28
- var import_path = require("path");
231
+ var import_fs2 = require("fs");
232
+ var import_path2 = require("path");
29
233
 
30
234
  // src/engine/worldmodel-parser.ts
31
235
  function splitSections(markdown) {
@@ -968,8 +1172,8 @@ function formatIssue(issue) {
968
1172
  return ` ${color}${icon}${RESET} [${issue.section}${lineRef}] ${issue.message}`;
969
1173
  }
970
1174
  async function readSourceFile(inputPath) {
971
- const fullPath = (0, import_path.resolve)(inputPath);
972
- if (!(0, import_fs.existsSync)(fullPath)) {
1175
+ const fullPath = (0, import_path2.resolve)(inputPath);
1176
+ if (!(0, import_fs2.existsSync)(fullPath)) {
973
1177
  process.stderr.write(`File not found: ${fullPath}
974
1178
  `);
975
1179
  process.exit(3);
@@ -993,30 +1197,105 @@ async function cmdInit(argv) {
993
1197
  const args = parseArgs(argv);
994
1198
  if (args.help) {
995
1199
  process.stdout.write(
996
- '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'
1200
+ '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'
997
1201
  );
998
1202
  return;
999
1203
  }
1000
1204
  const modelName = args.name || "My Behavioral Model";
1001
- const outputPath = (0, import_path.resolve)(
1205
+ const outputPath = (0, import_path2.resolve)(
1002
1206
  args.output || `./${toFileName(modelName)}.worldmodel.md`
1003
1207
  );
1004
- if ((0, import_fs.existsSync)(outputPath)) {
1208
+ if ((0, import_fs2.existsSync)(outputPath)) {
1005
1209
  process.stderr.write(`File already exists: ${outputPath}
1006
1210
  `);
1007
1211
  process.stderr.write("Use --output to specify a different path.\n");
1008
1212
  process.exit(1);
1009
1213
  }
1214
+ const apiKey = process.env.ANTHROPIC_API_KEY;
1215
+ const forceTemplate = argv.includes("--template");
1216
+ if (apiKey && !forceTemplate && process.stdin.isTTY) {
1217
+ const { askQuestions: askQuestions2, structureWorldmodel: structureWorldmodel2, saveWorldmodel: saveWorldmodel2 } = await Promise.resolve().then(() => (init_worldmodel_create(), worldmodel_create_exports));
1218
+ process.stderr.write(`
1219
+ `);
1220
+ const answers = await askQuestions2();
1221
+ process.stderr.write(`${DIM}Structuring your worldmodel...${RESET}
1222
+ `);
1223
+ try {
1224
+ const content = await structureWorldmodel2(answers, apiKey);
1225
+ const dir2 = (0, import_path2.dirname)(outputPath);
1226
+ if (!(0, import_fs2.existsSync)(dir2)) {
1227
+ await (0, import_promises.mkdir)(dir2, { recursive: true });
1228
+ }
1229
+ saveWorldmodel2(content, outputPath);
1230
+ process.stderr.write(`
1231
+ ${GREEN}Created${RESET} ${outputPath}
1232
+ `);
1233
+ process.stderr.write(
1234
+ `${DIM}Review the file, then run: neuroverse worldmodel validate ${(0, import_path2.basename)(outputPath)}${RESET}
1235
+ `
1236
+ );
1237
+ try {
1238
+ const validateResult = parseWorldModel(content);
1239
+ if (validateResult.model) {
1240
+ const m = validateResult.model;
1241
+ process.stderr.write(
1242
+ `${DIM} Domains: ${m.geometry.domains.length} Overlaps: ${m.geometry.overlapEffects.length} Signals: ${m.evolution.signals.length}${RESET}
1243
+ `
1244
+ );
1245
+ }
1246
+ const errors = validateResult.issues.filter((i) => i.severity === "error");
1247
+ if (errors.length > 0) {
1248
+ process.stderr.write(
1249
+ `
1250
+ ${YELLOW}Validation found ${errors.length} issue${errors.length > 1 ? "s" : ""} \u2014 review and fix:${RESET}
1251
+ `
1252
+ );
1253
+ for (const issue of errors) {
1254
+ process.stderr.write(` ${formatIssue(issue)}
1255
+ `);
1256
+ }
1257
+ } else {
1258
+ process.stderr.write(`${GREEN}Validates cleanly!${RESET}
1259
+ `);
1260
+ }
1261
+ } catch {
1262
+ }
1263
+ } catch (err) {
1264
+ process.stderr.write(`${RED}Error:${RESET} ${err}
1265
+ `);
1266
+ process.stderr.write(
1267
+ `${DIM}Falling back to template mode.${RESET}
1268
+
1269
+ `
1270
+ );
1271
+ const template2 = generateScaffold(modelName);
1272
+ const dir2 = (0, import_path2.dirname)(outputPath);
1273
+ if (!(0, import_fs2.existsSync)(dir2)) {
1274
+ await (0, import_promises.mkdir)(dir2, { recursive: true });
1275
+ }
1276
+ await (0, import_promises.writeFile)(outputPath, template2, "utf-8");
1277
+ process.stderr.write(`${GREEN}Created${RESET} ${outputPath} (template)
1278
+ `);
1279
+ }
1280
+ return;
1281
+ }
1282
+ if (!apiKey && !forceTemplate) {
1283
+ process.stderr.write(
1284
+ `${DIM}Tip: Set ANTHROPIC_API_KEY for the guided experience \u2014 AI asks you questions and creates your worldmodel.${RESET}
1285
+
1286
+ `
1287
+ );
1288
+ }
1010
1289
  const template = generateScaffold(modelName);
1011
- const dir = (0, import_path.dirname)(outputPath);
1012
- if (!(0, import_fs.existsSync)(dir)) {
1290
+ const dir = (0, import_path2.dirname)(outputPath);
1291
+ if (!(0, import_fs2.existsSync)(dir)) {
1013
1292
  await (0, import_promises.mkdir)(dir, { recursive: true });
1014
1293
  }
1015
1294
  await (0, import_promises.writeFile)(outputPath, template, "utf-8");
1016
1295
  process.stderr.write(`${GREEN}Created${RESET} ${outputPath}
1017
1296
  `);
1018
1297
  process.stderr.write(
1019
- `${DIM}Edit the template, then run: neuroverse worldmodel validate ${(0, import_path.basename)(outputPath)}${RESET}
1298
+ `${DIM}Edit the template, then run: neuroverse worldmodel validate ${(0, import_path2.basename)(outputPath)}${RESET}
1020
1299
  `
1021
1300
  );
1022
1301
  }
@@ -1447,17 +1726,17 @@ async function cmdBuild(argv) {
1447
1726
  process.stderr.write("\n");
1448
1727
  }
1449
1728
  const output = compileWorldModel(model);
1450
- const outputDir = (0, import_path.resolve)(
1729
+ const outputDir = (0, import_path2.resolve)(
1451
1730
  args.output || `.neuroverse/worldmodels/${model.frontmatter.model_id}/`
1452
1731
  );
1453
- if (!(0, import_fs.existsSync)(outputDir)) {
1732
+ if (!(0, import_fs2.existsSync)(outputDir)) {
1454
1733
  await (0, import_promises.mkdir)(outputDir, { recursive: true });
1455
1734
  }
1456
- const worldPath = (0, import_path.join)(outputDir, `${model.frontmatter.model_id}.nv-world.md`);
1457
- const signalsPath = (0, import_path.join)(outputDir, "signals.json");
1458
- const overlapsPath = (0, import_path.join)(outputDir, "overlaps.json");
1459
- const contextsPath = (0, import_path.join)(outputDir, "contexts.json");
1460
- const lensesPath = (0, import_path.join)(outputDir, "lenses.json");
1735
+ const worldPath = (0, import_path2.join)(outputDir, `${model.frontmatter.model_id}.nv-world.md`);
1736
+ const signalsPath = (0, import_path2.join)(outputDir, "signals.json");
1737
+ const overlapsPath = (0, import_path2.join)(outputDir, "overlaps.json");
1738
+ const contextsPath = (0, import_path2.join)(outputDir, "contexts.json");
1739
+ const lensesPath = (0, import_path2.join)(outputDir, "lenses.json");
1461
1740
  await Promise.all([
1462
1741
  (0, import_promises.writeFile)(worldPath, output.worldMarkdown, "utf-8"),
1463
1742
  (0, import_promises.writeFile)(signalsPath, JSON.stringify(output.signalSchema, null, 2) + "\n", "utf-8"),
@@ -1489,7 +1768,7 @@ async function cmdBuild(argv) {
1489
1768
  `);
1490
1769
  process.stderr.write(` ${BOLD}Output:${RESET} ${outputDir}/
1491
1770
  `);
1492
- process.stderr.write(` ${(0, import_path.basename)(worldPath)}${DIM} \u2014 executable world${RESET}
1771
+ process.stderr.write(` ${(0, import_path2.basename)(worldPath)}${DIM} \u2014 executable world${RESET}
1493
1772
  `);
1494
1773
  process.stderr.write(` signals.json${DIM} \u2014 signal schema${RESET}
1495
1774
  `);
@@ -1525,9 +1804,9 @@ async function cmdEmitWorld(argv) {
1525
1804
  const { model } = await loadAndParse(args.inputPath);
1526
1805
  const markdown = emitWorldMarkdown(model);
1527
1806
  if (args.output) {
1528
- const dir = (0, import_path.dirname)((0, import_path.resolve)(args.output));
1529
- if (!(0, import_fs.existsSync)(dir)) await (0, import_promises.mkdir)(dir, { recursive: true });
1530
- await (0, import_promises.writeFile)((0, import_path.resolve)(args.output), markdown, "utf-8");
1807
+ const dir = (0, import_path2.dirname)((0, import_path2.resolve)(args.output));
1808
+ if (!(0, import_fs2.existsSync)(dir)) await (0, import_promises.mkdir)(dir, { recursive: true });
1809
+ await (0, import_promises.writeFile)((0, import_path2.resolve)(args.output), markdown, "utf-8");
1531
1810
  process.stderr.write(`${GREEN}Written${RESET} ${args.output}
1532
1811
  `);
1533
1812
  } else {
@@ -112,7 +112,7 @@ async function cmdInit(argv) {
112
112
  const args = parseArgs(argv);
113
113
  if (args.help) {
114
114
  process.stdout.write(
115
- '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'
115
+ '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'
116
116
  );
117
117
  return;
118
118
  }
@@ -126,6 +126,81 @@ async function cmdInit(argv) {
126
126
  process.stderr.write("Use --output to specify a different path.\n");
127
127
  process.exit(1);
128
128
  }
129
+ const apiKey = process.env.ANTHROPIC_API_KEY;
130
+ const forceTemplate = argv.includes("--template");
131
+ if (apiKey && !forceTemplate && process.stdin.isTTY) {
132
+ const { askQuestions, structureWorldmodel, saveWorldmodel } = await import("../worldmodel-create-5SWHVNMQ.js");
133
+ process.stderr.write(`
134
+ `);
135
+ const answers = await askQuestions();
136
+ process.stderr.write(`${DIM}Structuring your worldmodel...${RESET}
137
+ `);
138
+ try {
139
+ const content = await structureWorldmodel(answers, apiKey);
140
+ const dir2 = dirname(outputPath);
141
+ if (!existsSync(dir2)) {
142
+ await mkdir(dir2, { recursive: true });
143
+ }
144
+ saveWorldmodel(content, outputPath);
145
+ process.stderr.write(`
146
+ ${GREEN}Created${RESET} ${outputPath}
147
+ `);
148
+ process.stderr.write(
149
+ `${DIM}Review the file, then run: neuroverse worldmodel validate ${basename(outputPath)}${RESET}
150
+ `
151
+ );
152
+ try {
153
+ const validateResult = parseWorldModel(content);
154
+ if (validateResult.model) {
155
+ const m = validateResult.model;
156
+ process.stderr.write(
157
+ `${DIM} Domains: ${m.geometry.domains.length} Overlaps: ${m.geometry.overlapEffects.length} Signals: ${m.evolution.signals.length}${RESET}
158
+ `
159
+ );
160
+ }
161
+ const errors = validateResult.issues.filter((i) => i.severity === "error");
162
+ if (errors.length > 0) {
163
+ process.stderr.write(
164
+ `
165
+ ${YELLOW}Validation found ${errors.length} issue${errors.length > 1 ? "s" : ""} \u2014 review and fix:${RESET}
166
+ `
167
+ );
168
+ for (const issue of errors) {
169
+ process.stderr.write(` ${formatIssue(issue)}
170
+ `);
171
+ }
172
+ } else {
173
+ process.stderr.write(`${GREEN}Validates cleanly!${RESET}
174
+ `);
175
+ }
176
+ } catch {
177
+ }
178
+ } catch (err) {
179
+ process.stderr.write(`${RED}Error:${RESET} ${err}
180
+ `);
181
+ process.stderr.write(
182
+ `${DIM}Falling back to template mode.${RESET}
183
+
184
+ `
185
+ );
186
+ const template2 = generateScaffold(modelName);
187
+ const dir2 = dirname(outputPath);
188
+ if (!existsSync(dir2)) {
189
+ await mkdir(dir2, { recursive: true });
190
+ }
191
+ await writeFile(outputPath, template2, "utf-8");
192
+ process.stderr.write(`${GREEN}Created${RESET} ${outputPath} (template)
193
+ `);
194
+ }
195
+ return;
196
+ }
197
+ if (!apiKey && !forceTemplate) {
198
+ process.stderr.write(
199
+ `${DIM}Tip: Set ANTHROPIC_API_KEY for the guided experience \u2014 AI asks you questions and creates your worldmodel.${RESET}
200
+
201
+ `
202
+ );
203
+ }
129
204
  const template = generateScaffold(modelName);
130
205
  const dir = dirname(outputPath);
131
206
  if (!existsSync(dir)) {
@@ -2,12 +2,14 @@ import {
2
2
  LENSES,
3
3
  aukiBuilderLens,
4
4
  getLens,
5
- listLenses
6
- } from "./chunk-VGFDMPVB.js";
5
+ listLenses,
6
+ sovereignConduitLens
7
+ } from "./chunk-F2LWMOM5.js";
7
8
  import "./chunk-QWGCMQQD.js";
8
9
  export {
9
10
  LENSES,
10
11
  aukiBuilderLens,
11
12
  getLens,
12
- listLenses
13
+ listLenses,
14
+ sovereignConduitLens
13
15
  };