@sprig-and-prose/sprig 0.3.2 β 0.3.3
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 +50 -23
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +94 -3
- package/dist/cli.js.map +1 -1
- package/package.json +3 -3
- package/src/cli.ts +99 -3
- package/tests/init.test.ts +109 -0
package/README.md
CHANGED
|
@@ -1,41 +1,68 @@
|
|
|
1
1
|
# sprig-cli
|
|
2
2
|
|
|
3
|
-
Sprig
|
|
3
|
+
Sprig is a calm way to explore and navigate **prose-defined universes**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It has no execution semantics, no runtime behavior, and no required framework.
|
|
6
|
+
Sprig exists to help humans understand complex systems by naming and relating ideas.
|
|
7
|
+
|
|
8
|
+
This repository contains the **Sprig command-line interface**, which renders and
|
|
9
|
+
navigates Sprig & Prose universes in the browser.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What this is
|
|
14
|
+
|
|
15
|
+
- A **viewer**, not a runtime
|
|
16
|
+
- A **navigator**, not a validator
|
|
17
|
+
- A **projection** of a prose-only universe
|
|
18
|
+
|
|
19
|
+
Sprig does not execute code.
|
|
20
|
+
It does not enforce behavior.
|
|
21
|
+
It helps you *see what exists* and *how things relate*.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
Install the CLI:
|
|
6
28
|
|
|
7
29
|
```bash
|
|
8
|
-
npm install -g @sprig-and-prose/sprig
|
|
9
|
-
|
|
30
|
+
npm install -g @sprig-and-prose/sprig
|
|
31
|
+
````
|
|
10
32
|
|
|
11
|
-
|
|
33
|
+
Open a universe:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
sprig ui
|
|
37
|
+
```
|
|
12
38
|
|
|
13
|
-
|
|
39
|
+
Sprig will open your universe in a browser and let you explore it interactively.
|
|
14
40
|
|
|
15
|
-
|
|
16
|
-
- `sprig validate [path?]` - Validate universe files (no output)
|
|
17
|
-
- `sprig ui [path?]` - Start UI server with watch mode
|
|
41
|
+
Thatβs it.
|
|
18
42
|
|
|
19
|
-
|
|
43
|
+
---
|
|
20
44
|
|
|
21
|
-
|
|
45
|
+
## Where to go next
|
|
22
46
|
|
|
23
|
-
|
|
47
|
+
π **Documentation, syntax reference, and design philosophy live at:**
|
|
48
|
+
**[https://sprig-and-prose.io](https://sprig-and-prose.io)**
|
|
24
49
|
|
|
25
|
-
|
|
50
|
+
Start here if you want to learn:
|
|
26
51
|
|
|
27
|
-
|
|
52
|
+
* what a universe is
|
|
53
|
+
* how prose is structured
|
|
54
|
+
* how concepts, relationships, and references work
|
|
55
|
+
* why Sprig deliberately avoids execution semantics
|
|
28
56
|
|
|
29
|
-
|
|
57
|
+
---
|
|
30
58
|
|
|
31
|
-
|
|
59
|
+
## What this repository is not
|
|
32
60
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- Watches `.prose` files and automatically rebuilds on changes
|
|
38
|
-
- Broadcasts SSE events after each successful rebuild
|
|
61
|
+
* A programming language
|
|
62
|
+
* A configuration system
|
|
63
|
+
* A validation framework
|
|
64
|
+
* A scene or execution engine
|
|
39
65
|
|
|
40
|
-
|
|
66
|
+
Those concerns live elsewhere β or may not exist at all.
|
|
41
67
|
|
|
68
|
+
Sprig favors **composition over extension** and **clarity over power**.
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAoNA,wBAAsB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ElF"}
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { resolve } from "node:path";
|
|
2
|
+
import { resolve, join } from "node:path";
|
|
3
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
3
4
|
import { discoverUniverseRoot } from "./root.js";
|
|
4
5
|
import { loadProseFiles } from "./prose.js";
|
|
5
6
|
import { compileUniverse } from "./compiler.js";
|
|
6
7
|
import { startUIServer } from "./ui.js";
|
|
7
|
-
const commands = ["compile", "validate", "ui"];
|
|
8
|
+
const commands = ["compile", "validate", "ui", "init"];
|
|
8
9
|
function printHelp() {
|
|
9
10
|
console.log("Usage: sprig <command> [path?] [options]");
|
|
10
11
|
console.log("");
|
|
@@ -12,6 +13,7 @@ function printHelp() {
|
|
|
12
13
|
console.log(" compile Compile universe files to manifest");
|
|
13
14
|
console.log(" validate Validate universe files (no output)");
|
|
14
15
|
console.log(" ui Start UI server with watch mode");
|
|
16
|
+
console.log(" init Initialize a new universe repository");
|
|
15
17
|
console.log("");
|
|
16
18
|
console.log("Options (for ui command):");
|
|
17
19
|
console.log(" -p, --port <number> Port to listen on (default: 6336)");
|
|
@@ -31,6 +33,14 @@ function parseArgs() {
|
|
|
31
33
|
console.error("Run 'sprig --help' for usage information");
|
|
32
34
|
process.exit(1);
|
|
33
35
|
}
|
|
36
|
+
// Special handling for init command
|
|
37
|
+
if (command === "init") {
|
|
38
|
+
if (args.length < 2) {
|
|
39
|
+
console.error("Usage: sprig init <UniverseName>");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
return { command, path: process.cwd(), universeName: args[1] };
|
|
43
|
+
}
|
|
34
44
|
// Parse path and options
|
|
35
45
|
let path = process.cwd();
|
|
36
46
|
let port;
|
|
@@ -153,6 +163,80 @@ function formatSource(source) {
|
|
|
153
163
|
}
|
|
154
164
|
return `${span.file}:${line}${col ? `:${col}` : ""}`;
|
|
155
165
|
}
|
|
166
|
+
export async function handleInit(universeName, path) {
|
|
167
|
+
if (!universeName) {
|
|
168
|
+
console.error("Usage: sprig init <UniverseName>");
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
const universeProsePath = join(path, "universe.prose");
|
|
172
|
+
const readmePath = join(path, "readme.md");
|
|
173
|
+
const universeProseExists = existsSync(universeProsePath);
|
|
174
|
+
const readmeExists = existsSync(readmePath);
|
|
175
|
+
let createdAny = false;
|
|
176
|
+
try {
|
|
177
|
+
if (!universeProseExists) {
|
|
178
|
+
const universeProseContent = `universe ${universeName} {
|
|
179
|
+
note {
|
|
180
|
+
This universe is prose-first.
|
|
181
|
+
|
|
182
|
+
It contains no executable code.
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
`;
|
|
186
|
+
writeFileSync(universeProsePath, universeProseContent, "utf-8");
|
|
187
|
+
console.log("β universe.prose created");
|
|
188
|
+
createdAny = true;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
console.log("β universe.prose already exists β leaving it unchanged");
|
|
192
|
+
}
|
|
193
|
+
if (!readmeExists) {
|
|
194
|
+
const readmeContent = `# ${universeName}
|
|
195
|
+
|
|
196
|
+
This repository contains the **universe definition** for ${universeName}.
|
|
197
|
+
|
|
198
|
+
It is written in **prose**, a human-readable language for naming and relating ideas without execution semantics.
|
|
199
|
+
|
|
200
|
+
## What lives here
|
|
201
|
+
|
|
202
|
+
- Concepts and their meanings
|
|
203
|
+
- Relationships between ideas
|
|
204
|
+
- Structural organization (series, books, chapters)
|
|
205
|
+
- References to external material (code, docs, data)
|
|
206
|
+
|
|
207
|
+
This repository contains **no executable code**.
|
|
208
|
+
|
|
209
|
+
## Learn more
|
|
210
|
+
|
|
211
|
+
- sprig & prose: https://sprig-and-prose.io
|
|
212
|
+
- language reference: https://sprig-and-prose.io/reference
|
|
213
|
+
|
|
214
|
+
## Notes
|
|
215
|
+
|
|
216
|
+
This universe is expected to evolve over time as understanding deepens.
|
|
217
|
+
|
|
218
|
+
Structure may change. Meaning is preserved.
|
|
219
|
+
`;
|
|
220
|
+
writeFileSync(readmePath, readmeContent, "utf-8");
|
|
221
|
+
console.log("β readme.md created");
|
|
222
|
+
createdAny = true;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
console.log("β readme.md already exists β leaving it unchanged");
|
|
226
|
+
}
|
|
227
|
+
if (createdAny) {
|
|
228
|
+
console.log("Universe initialized.");
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
console.log("Universe already initialized.");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
236
|
+
console.error(`Error: ${message}`);
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
156
240
|
async function handleUI(path, port) {
|
|
157
241
|
const root = discoverUniverseRoot(path);
|
|
158
242
|
if (!root) {
|
|
@@ -164,7 +248,7 @@ async function handleUI(path, port) {
|
|
|
164
248
|
await startUIServer(root, port);
|
|
165
249
|
}
|
|
166
250
|
async function main() {
|
|
167
|
-
const { command, path, port } = parseArgs();
|
|
251
|
+
const { command, path, port, universeName } = parseArgs();
|
|
168
252
|
if (!command) {
|
|
169
253
|
printHelp();
|
|
170
254
|
process.exit(0);
|
|
@@ -180,6 +264,13 @@ async function main() {
|
|
|
180
264
|
case "ui":
|
|
181
265
|
await handleUI(path, port);
|
|
182
266
|
break;
|
|
267
|
+
case "init":
|
|
268
|
+
if (!universeName) {
|
|
269
|
+
console.error("Usage: sprig init <UniverseName>");
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
await handleInit(universeName, path);
|
|
273
|
+
break;
|
|
183
274
|
}
|
|
184
275
|
}
|
|
185
276
|
catch (error) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAU,CAAC;AAGhE,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,SAAS;IAMhB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAY,CAAC;IACnC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,GAAG,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oCAAoC;IACpC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,CAAC;IAED,yBAAyB;IACzB,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,IAAwB,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACrC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAC3C,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,KAAK,EAAE,CAAC;gBAC9D,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;gBACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,IAAI,GAAG,UAAU,CAAC;YAClB,CAAC,EAAE,CAAC,CAAC,sBAAsB;QAC7B,CAAC;aAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,wCAAwC;YACxC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,GAAG,CAAC,CAAC;YAChD,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAY;IACvC,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAExD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QACxE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAEzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QACxE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAID,SAAS,gBAAgB,CAAC,WAAyB,EAAE,KAA0B;IAC7E,MAAM,OAAO,GAAG,IAAI,GAAG,EAGpB,CAAC;IAEJ,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,MAAM,KAAK,GACT,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;QACjF,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;QACjB,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC;gBAChC,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACpC,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,EAAE,KAAK,EAAE,EAAE;QACrE,MAAM,MAAM,GAAG,YAAY,CAAC,oBAAoB,EAAE,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,GAAG,KAAK,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,GAAG,SAAS,EAAE,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,MAAe;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,MAOjB,CAAC;IAEF,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC;IACjE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC;IAE7C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,YAAoB,EAAE,IAAY;IACjE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAE3C,MAAM,mBAAmB,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAE5C,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,IAAI,CAAC;QACH,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,MAAM,oBAAoB,GAAG,YAAY,YAAY;;;;;;;CAO1D,CAAC;YACI,aAAa,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YACxC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,aAAa,GAAG,KAAK,YAAY;;2DAEc,YAAY;;;;;;;;;;;;;;;;;;;;;;;CAuBtE,CAAC;YACI,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAa;IACjD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,CAAC;IAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,SAAS;gBACZ,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC1B,MAAM;YACR,KAAK,UAAU;gBACb,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;gBAC3B,MAAM;YACR,KAAK,IAAI;gBACP,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC3B,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;oBAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBACD,MAAM,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;gBACrC,MAAM;QACV,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sprig-and-prose/sprig",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Sprig CLI tool for compiling and serving universes",
|
|
6
6
|
"main": "dist/cli.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"author": "",
|
|
20
20
|
"license": "ISC",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@sprig-and-prose/sprig-universe": "0.3.
|
|
23
|
-
"@sprig-and-prose/sprig-ui-csr": "0.2.
|
|
22
|
+
"@sprig-and-prose/sprig-universe": "^0.3.2",
|
|
23
|
+
"@sprig-and-prose/sprig-ui-csr": "^0.2.3",
|
|
24
24
|
"chokidar": "^3.6.0",
|
|
25
25
|
"fast-glob": "^3.3.2"
|
|
26
26
|
},
|
package/src/cli.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { resolve } from "node:path";
|
|
3
|
+
import { resolve, join } from "node:path";
|
|
4
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
4
5
|
import { discoverUniverseRoot } from "./root.js";
|
|
5
6
|
import { loadProseFiles } from "./prose.js";
|
|
6
7
|
import { compileUniverse } from "./compiler.js";
|
|
7
8
|
import { startUIServer } from "./ui.js";
|
|
8
9
|
|
|
9
|
-
const commands = ["compile", "validate", "ui"] as const;
|
|
10
|
+
const commands = ["compile", "validate", "ui", "init"] as const;
|
|
10
11
|
type Command = (typeof commands)[number];
|
|
11
12
|
|
|
12
13
|
function printHelp() {
|
|
@@ -16,6 +17,7 @@ function printHelp() {
|
|
|
16
17
|
console.log(" compile Compile universe files to manifest");
|
|
17
18
|
console.log(" validate Validate universe files (no output)");
|
|
18
19
|
console.log(" ui Start UI server with watch mode");
|
|
20
|
+
console.log(" init Initialize a new universe repository");
|
|
19
21
|
console.log("");
|
|
20
22
|
console.log("Options (for ui command):");
|
|
21
23
|
console.log(" -p, --port <number> Port to listen on (default: 6336)");
|
|
@@ -29,6 +31,7 @@ function parseArgs(): {
|
|
|
29
31
|
command: Command | null;
|
|
30
32
|
path: string;
|
|
31
33
|
port?: number;
|
|
34
|
+
universeName?: string;
|
|
32
35
|
} {
|
|
33
36
|
const args = process.argv.slice(2);
|
|
34
37
|
|
|
@@ -43,6 +46,15 @@ function parseArgs(): {
|
|
|
43
46
|
process.exit(1);
|
|
44
47
|
}
|
|
45
48
|
|
|
49
|
+
// Special handling for init command
|
|
50
|
+
if (command === "init") {
|
|
51
|
+
if (args.length < 2) {
|
|
52
|
+
console.error("Usage: sprig init <UniverseName>");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
return { command, path: process.cwd(), universeName: args[1] };
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
// Parse path and options
|
|
47
59
|
let path = process.cwd();
|
|
48
60
|
let port: number | undefined;
|
|
@@ -198,6 +210,83 @@ function formatSource(source: unknown): string | null {
|
|
|
198
210
|
return `${span.file}:${line}${col ? `:${col}` : ""}`;
|
|
199
211
|
}
|
|
200
212
|
|
|
213
|
+
export async function handleInit(universeName: string, path: string): Promise<void> {
|
|
214
|
+
if (!universeName) {
|
|
215
|
+
console.error("Usage: sprig init <UniverseName>");
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const universeProsePath = join(path, "universe.prose");
|
|
220
|
+
const readmePath = join(path, "readme.md");
|
|
221
|
+
|
|
222
|
+
const universeProseExists = existsSync(universeProsePath);
|
|
223
|
+
const readmeExists = existsSync(readmePath);
|
|
224
|
+
|
|
225
|
+
let createdAny = false;
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
if (!universeProseExists) {
|
|
229
|
+
const universeProseContent = `universe ${universeName} {
|
|
230
|
+
note {
|
|
231
|
+
This universe is prose-first.
|
|
232
|
+
|
|
233
|
+
It contains no executable code.
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
`;
|
|
237
|
+
writeFileSync(universeProsePath, universeProseContent, "utf-8");
|
|
238
|
+
console.log("β universe.prose created");
|
|
239
|
+
createdAny = true;
|
|
240
|
+
} else {
|
|
241
|
+
console.log("β universe.prose already exists β leaving it unchanged");
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (!readmeExists) {
|
|
245
|
+
const readmeContent = `# ${universeName}
|
|
246
|
+
|
|
247
|
+
This repository contains the **universe definition** for ${universeName}.
|
|
248
|
+
|
|
249
|
+
It is written in **prose**, a human-readable language for naming and relating ideas without execution semantics.
|
|
250
|
+
|
|
251
|
+
## What lives here
|
|
252
|
+
|
|
253
|
+
- Concepts and their meanings
|
|
254
|
+
- Relationships between ideas
|
|
255
|
+
- Structural organization (series, books, chapters)
|
|
256
|
+
- References to external material (code, docs, data)
|
|
257
|
+
|
|
258
|
+
This repository contains **no executable code**.
|
|
259
|
+
|
|
260
|
+
## Learn more
|
|
261
|
+
|
|
262
|
+
- sprig & prose: https://sprig-and-prose.io
|
|
263
|
+
- language reference: https://sprig-and-prose.io/reference
|
|
264
|
+
|
|
265
|
+
## Notes
|
|
266
|
+
|
|
267
|
+
This universe is expected to evolve over time as understanding deepens.
|
|
268
|
+
|
|
269
|
+
Structure may change. Meaning is preserved.
|
|
270
|
+
`;
|
|
271
|
+
writeFileSync(readmePath, readmeContent, "utf-8");
|
|
272
|
+
console.log("β readme.md created");
|
|
273
|
+
createdAny = true;
|
|
274
|
+
} else {
|
|
275
|
+
console.log("β readme.md already exists β leaving it unchanged");
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (createdAny) {
|
|
279
|
+
console.log("Universe initialized.");
|
|
280
|
+
} else {
|
|
281
|
+
console.log("Universe already initialized.");
|
|
282
|
+
}
|
|
283
|
+
} catch (error) {
|
|
284
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
285
|
+
console.error(`Error: ${message}`);
|
|
286
|
+
process.exit(1);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
201
290
|
async function handleUI(path: string, port?: number): Promise<void> {
|
|
202
291
|
const root = discoverUniverseRoot(path);
|
|
203
292
|
if (!root) {
|
|
@@ -211,7 +300,7 @@ async function handleUI(path: string, port?: number): Promise<void> {
|
|
|
211
300
|
}
|
|
212
301
|
|
|
213
302
|
async function main() {
|
|
214
|
-
const { command, path, port } = parseArgs();
|
|
303
|
+
const { command, path, port, universeName } = parseArgs();
|
|
215
304
|
|
|
216
305
|
if (!command) {
|
|
217
306
|
printHelp();
|
|
@@ -229,6 +318,13 @@ async function main() {
|
|
|
229
318
|
case "ui":
|
|
230
319
|
await handleUI(path, port);
|
|
231
320
|
break;
|
|
321
|
+
case "init":
|
|
322
|
+
if (!universeName) {
|
|
323
|
+
console.error("Usage: sprig init <UniverseName>");
|
|
324
|
+
process.exit(1);
|
|
325
|
+
}
|
|
326
|
+
await handleInit(universeName, path);
|
|
327
|
+
break;
|
|
232
328
|
}
|
|
233
329
|
} catch (error) {
|
|
234
330
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import { strict as assert } from "node:assert";
|
|
3
|
+
import { mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { handleInit } from "../src/cli.js";
|
|
7
|
+
|
|
8
|
+
test("init creates both files when directory is empty", async () => {
|
|
9
|
+
const testDir = join(tmpdir(), `sprig-test-${Date.now()}`);
|
|
10
|
+
mkdirSync(testDir, { recursive: true });
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
await handleInit("Primer", testDir);
|
|
14
|
+
|
|
15
|
+
const universeProsePath = join(testDir, "universe.prose");
|
|
16
|
+
const readmePath = join(testDir, "readme.md");
|
|
17
|
+
|
|
18
|
+
assert.ok(existsSync(universeProsePath), "universe.prose should exist");
|
|
19
|
+
assert.ok(existsSync(readmePath), "readme.md should exist");
|
|
20
|
+
|
|
21
|
+
const universeProseContent = readFileSync(universeProsePath, "utf-8");
|
|
22
|
+
assert.ok(universeProseContent.includes("universe Primer"), "universe.prose should contain universe name");
|
|
23
|
+
|
|
24
|
+
const readmeContent = readFileSync(readmePath, "utf-8");
|
|
25
|
+
assert.ok(readmeContent.includes("# Primer"), "readme.md should contain universe name");
|
|
26
|
+
assert.ok(readmeContent.includes("**prose**"), "readme.md should mention prose");
|
|
27
|
+
} finally {
|
|
28
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("init does not overwrite existing files", async () => {
|
|
33
|
+
const testDir = join(tmpdir(), `sprig-test-${Date.now()}`);
|
|
34
|
+
mkdirSync(testDir, { recursive: true });
|
|
35
|
+
|
|
36
|
+
const universeProsePath = join(testDir, "universe.prose");
|
|
37
|
+
const readmePath = join(testDir, "readme.md");
|
|
38
|
+
|
|
39
|
+
const originalUniverseContent = "universe Original {}";
|
|
40
|
+
const originalReadmeContent = "# Original\n\nOriginal content.";
|
|
41
|
+
|
|
42
|
+
writeFileSync(universeProsePath, originalUniverseContent, "utf-8");
|
|
43
|
+
writeFileSync(readmePath, originalReadmeContent, "utf-8");
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
await handleInit("NewUniverse", testDir);
|
|
47
|
+
|
|
48
|
+
const universeProseContent = readFileSync(universeProsePath, "utf-8");
|
|
49
|
+
assert.strictEqual(universeProseContent, originalUniverseContent, "universe.prose should not be overwritten");
|
|
50
|
+
|
|
51
|
+
const readmeContent = readFileSync(readmePath, "utf-8");
|
|
52
|
+
assert.strictEqual(readmeContent, originalReadmeContent, "readme.md should not be overwritten");
|
|
53
|
+
} finally {
|
|
54
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("init handles partial file existence correctly", async () => {
|
|
59
|
+
const testDir = join(tmpdir(), `sprig-test-${Date.now()}`);
|
|
60
|
+
mkdirSync(testDir, { recursive: true });
|
|
61
|
+
|
|
62
|
+
const universeProsePath = join(testDir, "universe.prose");
|
|
63
|
+
const readmePath = join(testDir, "readme.md");
|
|
64
|
+
|
|
65
|
+
const originalUniverseContent = "universe Existing {}";
|
|
66
|
+
writeFileSync(universeProsePath, originalUniverseContent, "utf-8");
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
await handleInit("PartialTest", testDir);
|
|
70
|
+
|
|
71
|
+
// universe.prose should remain unchanged
|
|
72
|
+
const universeProseContent = readFileSync(universeProsePath, "utf-8");
|
|
73
|
+
assert.strictEqual(universeProseContent, originalUniverseContent, "universe.prose should not be overwritten");
|
|
74
|
+
|
|
75
|
+
// readme.md should be created
|
|
76
|
+
assert.ok(existsSync(readmePath), "readme.md should be created");
|
|
77
|
+
const readmeContent = readFileSync(readmePath, "utf-8");
|
|
78
|
+
assert.ok(readmeContent.includes("# PartialTest"), "readme.md should contain new universe name");
|
|
79
|
+
} finally {
|
|
80
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("init handles reverse partial file existence correctly", async () => {
|
|
85
|
+
const testDir = join(tmpdir(), `sprig-test-${Date.now()}`);
|
|
86
|
+
mkdirSync(testDir, { recursive: true });
|
|
87
|
+
|
|
88
|
+
const universeProsePath = join(testDir, "universe.prose");
|
|
89
|
+
const readmePath = join(testDir, "readme.md");
|
|
90
|
+
|
|
91
|
+
const originalReadmeContent = "# Existing\n\nExisting readme.";
|
|
92
|
+
writeFileSync(readmePath, originalReadmeContent, "utf-8");
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
await handleInit("ReversePartialTest", testDir);
|
|
96
|
+
|
|
97
|
+
// readme.md should remain unchanged
|
|
98
|
+
const readmeContent = readFileSync(readmePath, "utf-8");
|
|
99
|
+
assert.strictEqual(readmeContent, originalReadmeContent, "readme.md should not be overwritten");
|
|
100
|
+
|
|
101
|
+
// universe.prose should be created
|
|
102
|
+
assert.ok(existsSync(universeProsePath), "universe.prose should be created");
|
|
103
|
+
const universeProseContent = readFileSync(universeProsePath, "utf-8");
|
|
104
|
+
assert.ok(universeProseContent.includes("universe ReversePartialTest"), "universe.prose should contain new universe name");
|
|
105
|
+
} finally {
|
|
106
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|