@sprig-and-prose/sprig 0.1.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 +41 -0
- package/biome.json +32 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +161 -0
- package/dist/cli.js.map +1 -0
- package/dist/compiler.d.ts +21 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +117 -0
- package/dist/compiler.js.map +1 -0
- package/dist/prose.d.ts +7 -0
- package/dist/prose.d.ts.map +1 -0
- package/dist/prose.js +18 -0
- package/dist/prose.js.map +1 -0
- package/dist/root.d.ts +7 -0
- package/dist/root.d.ts.map +1 -0
- package/dist/root.js +25 -0
- package/dist/root.js.map +1 -0
- package/dist/ui.d.ts +5 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +293 -0
- package/dist/ui.js.map +1 -0
- package/package.json +33 -0
- package/src/cli.ts +186 -0
- package/src/compiler.ts +142 -0
- package/src/prose.ts +21 -0
- package/src/root.ts +29 -0
- package/src/ui.ts +336 -0
- package/tests/compile.test.d.ts +2 -0
- package/tests/compile.test.d.ts.map +1 -0
- package/tests/compile.test.js +64 -0
- package/tests/compile.test.js.map +1 -0
- package/tests/compile.test.ts +87 -0
- package/tests/root.test.d.ts +2 -0
- package/tests/root.test.d.ts.map +1 -0
- package/tests/root.test.js +43 -0
- package/tests/root.test.js.map +1 -0
- package/tests/root.test.ts +46 -0
- package/tsconfig.json +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# sprig-cli
|
|
2
|
+
|
|
3
|
+
Sprig CLI tool for compiling and serving universes.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @sprig-and-prose/sprig-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Commands
|
|
14
|
+
|
|
15
|
+
- `sprig compile [path?]` - Compile universe files to manifest
|
|
16
|
+
- `sprig validate [path?]` - Validate universe files (no output)
|
|
17
|
+
- `sprig ui [path?]` - Start UI server with watch mode
|
|
18
|
+
|
|
19
|
+
### Root Discovery
|
|
20
|
+
|
|
21
|
+
The CLI walks upward from the provided path (or current directory) until it finds a directory containing `universe.prose`. That directory is the universe root.
|
|
22
|
+
|
|
23
|
+
### Compile
|
|
24
|
+
|
|
25
|
+
Compiles all `.prose` files under the universe root (excluding `.sprig/**`, `dist/**`, `node_modules/**`, `.git/**`) and writes `.sprig/manifest.json`.
|
|
26
|
+
|
|
27
|
+
### Validate
|
|
28
|
+
|
|
29
|
+
Validates the universe without writing output. Exits with a nonzero code if errors are found.
|
|
30
|
+
|
|
31
|
+
### UI
|
|
32
|
+
|
|
33
|
+
Starts a local HTTP server (default port 5173) that:
|
|
34
|
+
- Serves the UI from `@sprig-and-prose/sprig-ui-csr`
|
|
35
|
+
- Provides `/api/manifest` endpoint for the compiled manifest
|
|
36
|
+
- Provides `/api/events` endpoint for Server-Sent Events (SSE) updates
|
|
37
|
+
- Watches `.prose` files and automatically rebuilds on changes
|
|
38
|
+
- Broadcasts SSE events after each successful rebuild
|
|
39
|
+
|
|
40
|
+
The `.sprig/` directory is a cache and should not be committed.
|
|
41
|
+
|
package/biome.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": true
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false,
|
|
10
|
+
"ignore": []
|
|
11
|
+
},
|
|
12
|
+
"formatter": {
|
|
13
|
+
"enabled": true,
|
|
14
|
+
"indentStyle": "space",
|
|
15
|
+
"indentWidth": 2
|
|
16
|
+
},
|
|
17
|
+
"organizeImports": {
|
|
18
|
+
"enabled": true
|
|
19
|
+
},
|
|
20
|
+
"linter": {
|
|
21
|
+
"enabled": true,
|
|
22
|
+
"rules": {
|
|
23
|
+
"recommended": true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"javascript": {
|
|
27
|
+
"formatter": {
|
|
28
|
+
"quoteStyle": "double"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { discoverUniverseRoot } from "./root.js";
|
|
4
|
+
import { loadProseFiles } from "./prose.js";
|
|
5
|
+
import { compileUniverse } from "./compiler.js";
|
|
6
|
+
import { startUIServer } from "./ui.js";
|
|
7
|
+
const commands = ["compile", "validate", "ui"];
|
|
8
|
+
function printHelp() {
|
|
9
|
+
console.log("Usage: sprig <command> [path?] [options]");
|
|
10
|
+
console.log("");
|
|
11
|
+
console.log("Commands:");
|
|
12
|
+
console.log(" compile Compile universe files to manifest");
|
|
13
|
+
console.log(" validate Validate universe files (no output)");
|
|
14
|
+
console.log(" ui Start UI server with watch mode");
|
|
15
|
+
console.log("");
|
|
16
|
+
console.log("Options (for ui command):");
|
|
17
|
+
console.log(" -p, --port <number> Port to listen on (default: 6336)");
|
|
18
|
+
console.log("");
|
|
19
|
+
console.log("Root discovery:");
|
|
20
|
+
console.log(" - Walks upward from provided path (or current directory)");
|
|
21
|
+
console.log(" - Finds directory containing universe.prose");
|
|
22
|
+
}
|
|
23
|
+
function parseArgs() {
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
26
|
+
return { command: null, path: process.cwd() };
|
|
27
|
+
}
|
|
28
|
+
const command = args[0];
|
|
29
|
+
if (!commands.includes(command)) {
|
|
30
|
+
console.error(`Error: Unknown command "${command}"`);
|
|
31
|
+
console.error("Run 'sprig --help' for usage information");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
// Parse path and options
|
|
35
|
+
let path = process.cwd();
|
|
36
|
+
let port;
|
|
37
|
+
for (let i = 1; i < args.length; i++) {
|
|
38
|
+
const arg = args[i];
|
|
39
|
+
if (arg === "--port" || arg === "-p") {
|
|
40
|
+
const portValue = args[i + 1];
|
|
41
|
+
if (!portValue) {
|
|
42
|
+
console.error("Error: --port requires a value");
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const parsedPort = parseInt(portValue, 10);
|
|
46
|
+
if (isNaN(parsedPort) || parsedPort < 1 || parsedPort > 65535) {
|
|
47
|
+
console.error("Error: --port must be a number between 1 and 65535");
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
port = parsedPort;
|
|
51
|
+
i++; // Skip the port value
|
|
52
|
+
}
|
|
53
|
+
else if (!arg.startsWith("-")) {
|
|
54
|
+
// First non-option argument is the path
|
|
55
|
+
path = resolve(arg);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.error(`Error: Unknown option "${arg}"`);
|
|
59
|
+
console.error("Run 'sprig --help' for usage information");
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { command, path, port };
|
|
64
|
+
}
|
|
65
|
+
async function handleCompile(path) {
|
|
66
|
+
const root = discoverUniverseRoot(path);
|
|
67
|
+
if (!root) {
|
|
68
|
+
console.error("Couldn't find universe.prose");
|
|
69
|
+
console.error("");
|
|
70
|
+
console.error("Make sure you're inside a universe repository.");
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
const files = await loadProseFiles(root);
|
|
74
|
+
const result = await compileUniverse(root, files, true);
|
|
75
|
+
if (!result.success) {
|
|
76
|
+
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
77
|
+
if (errors.length > 0) {
|
|
78
|
+
for (const error of errors) {
|
|
79
|
+
console.error(`Error: ${error.message}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
const warnings = result.diagnostics.filter((d) => d.severity === "warning");
|
|
85
|
+
if (warnings.length > 0) {
|
|
86
|
+
for (const warning of warnings) {
|
|
87
|
+
const source = warning.source
|
|
88
|
+
? // @ts-expect-error - source structure may vary
|
|
89
|
+
`${warning.source.file}:${warning.source.start?.line}:${warning.source.start?.col}`
|
|
90
|
+
: "unknown location";
|
|
91
|
+
console.warn(`Warning: ${source}: ${warning.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function handleValidate(path) {
|
|
96
|
+
const root = discoverUniverseRoot(path);
|
|
97
|
+
if (!root) {
|
|
98
|
+
console.error("Couldn't find universe.prose");
|
|
99
|
+
console.error("");
|
|
100
|
+
console.error("Make sure you're inside a universe repository.");
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
const files = await loadProseFiles(root);
|
|
104
|
+
const result = await compileUniverse(root, files, false);
|
|
105
|
+
if (!result.success) {
|
|
106
|
+
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
107
|
+
if (errors.length > 0) {
|
|
108
|
+
for (const error of errors) {
|
|
109
|
+
console.error(`Error: ${error.message}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
const warnings = result.diagnostics.filter((d) => d.severity === "warning");
|
|
115
|
+
if (warnings.length > 0) {
|
|
116
|
+
for (const warning of warnings) {
|
|
117
|
+
const source = warning.source
|
|
118
|
+
? // @ts-expect-error - source structure may vary
|
|
119
|
+
`${warning.source.file}:${warning.source.start?.line}:${warning.source.start?.col}`
|
|
120
|
+
: "unknown location";
|
|
121
|
+
console.warn(`Warning: ${source}: ${warning.message}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function handleUI(path, port) {
|
|
126
|
+
const root = discoverUniverseRoot(path);
|
|
127
|
+
if (!root) {
|
|
128
|
+
console.error("Couldn't find universe.prose");
|
|
129
|
+
console.error("");
|
|
130
|
+
console.error("Make sure you're inside a universe repository.");
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
await startUIServer(root, port);
|
|
134
|
+
}
|
|
135
|
+
async function main() {
|
|
136
|
+
const { command, path, port } = parseArgs();
|
|
137
|
+
if (!command) {
|
|
138
|
+
printHelp();
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
switch (command) {
|
|
143
|
+
case "compile":
|
|
144
|
+
await handleCompile(path);
|
|
145
|
+
break;
|
|
146
|
+
case "validate":
|
|
147
|
+
await handleValidate(path);
|
|
148
|
+
break;
|
|
149
|
+
case "ui":
|
|
150
|
+
await handleUI(path, port);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
156
|
+
console.error(`Error: ${message}`);
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
main();
|
|
161
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface CompileResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
manifest?: Record<string, unknown> & {
|
|
4
|
+
repositories?: Record<string, unknown>;
|
|
5
|
+
generatedAt: string;
|
|
6
|
+
};
|
|
7
|
+
diagnostics: Array<{
|
|
8
|
+
severity: string;
|
|
9
|
+
message: string;
|
|
10
|
+
source?: unknown;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compiles prose files into a manifest
|
|
15
|
+
* @param universeRoot - Universe root directory
|
|
16
|
+
* @param files - Array of prose file paths
|
|
17
|
+
* @param writeManifest - If true, write manifest to disk
|
|
18
|
+
* @returns Compile result with success status, manifest, and diagnostics
|
|
19
|
+
*/
|
|
20
|
+
export declare function compileUniverse(universeRoot: string, files: string[], writeManifest?: boolean): Promise<CompileResult>;
|
|
21
|
+
//# sourceMappingURL=compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACrG,WAAW,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC7E;AA2CD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,UAAO,GACnB,OAAO,CAAC,aAAa,CAAC,CA6ExB"}
|
package/dist/compiler.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, renameSync } from "node:fs";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
// @ts-expect-error - sprig-universe doesn't have TypeScript types
|
|
4
|
+
import { parseFiles } from "@sprig-and-prose/sprig-universe";
|
|
5
|
+
/**
|
|
6
|
+
* Validates that exactly one universe declaration exists in the parsed graph
|
|
7
|
+
*/
|
|
8
|
+
function validateUniverseCount(graph) {
|
|
9
|
+
const universes = graph.universes;
|
|
10
|
+
const universeNames = Object.keys(universes || {});
|
|
11
|
+
if (universeNames.length === 0) {
|
|
12
|
+
return {
|
|
13
|
+
valid: false,
|
|
14
|
+
error: "No universe declaration found. At least one universe declaration is required.",
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (universeNames.length > 1) {
|
|
18
|
+
const nodes = graph.nodes;
|
|
19
|
+
const fileList = Array.from(universeNames)
|
|
20
|
+
.map((name) => {
|
|
21
|
+
const universe = universes?.[name];
|
|
22
|
+
const rootNode = universe?.root && nodes ? nodes[universe.root] : null;
|
|
23
|
+
return rootNode?.source?.file || "unknown";
|
|
24
|
+
})
|
|
25
|
+
.filter((file, index, arr) => arr.indexOf(file) === index) // unique files
|
|
26
|
+
.sort()
|
|
27
|
+
.join(", ");
|
|
28
|
+
return {
|
|
29
|
+
valid: false,
|
|
30
|
+
error: `Multiple distinct universes found: ${universeNames.join(", ")}. Files: ${fileList}. Exactly one universe declaration is required.`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
valid: true,
|
|
35
|
+
universeName: universeNames[0],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Compiles prose files into a manifest
|
|
40
|
+
* @param universeRoot - Universe root directory
|
|
41
|
+
* @param files - Array of prose file paths
|
|
42
|
+
* @param writeManifest - If true, write manifest to disk
|
|
43
|
+
* @returns Compile result with success status, manifest, and diagnostics
|
|
44
|
+
*/
|
|
45
|
+
export async function compileUniverse(universeRoot, files, writeManifest = true) {
|
|
46
|
+
const manifestPath = join(universeRoot, ".sprig", "manifest.json");
|
|
47
|
+
// Read and parse files
|
|
48
|
+
const fileContents = files.map((file) => ({
|
|
49
|
+
file,
|
|
50
|
+
text: readFileSync(file, "utf-8"),
|
|
51
|
+
}));
|
|
52
|
+
try {
|
|
53
|
+
const graph = parseFiles(fileContents);
|
|
54
|
+
// Validate exactly one universe
|
|
55
|
+
const validation = validateUniverseCount(graph);
|
|
56
|
+
if (!validation.valid) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
diagnostics: [
|
|
60
|
+
{
|
|
61
|
+
severity: "error",
|
|
62
|
+
message: validation.error || "Unknown validation error",
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Add repositories and metadata to manifest
|
|
68
|
+
const manifest = {
|
|
69
|
+
...graph,
|
|
70
|
+
repositories: graph.repositories || {},
|
|
71
|
+
generatedAt: new Date().toISOString(),
|
|
72
|
+
};
|
|
73
|
+
// Check for parsing errors
|
|
74
|
+
const hasErrors = graph.diagnostics.some((d) => d.severity === "error");
|
|
75
|
+
if (hasErrors) {
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
manifest,
|
|
79
|
+
diagnostics: graph.diagnostics,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// Write manifest if requested
|
|
83
|
+
if (writeManifest) {
|
|
84
|
+
// Ensure output directory exists
|
|
85
|
+
const manifestDir = dirname(manifestPath);
|
|
86
|
+
try {
|
|
87
|
+
mkdirSync(manifestDir, { recursive: true });
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
// Directory might already exist, ignore
|
|
91
|
+
}
|
|
92
|
+
// Write atomically (temp file + rename)
|
|
93
|
+
const tempPath = `${manifestPath}.tmp`;
|
|
94
|
+
const json = JSON.stringify(manifest, null, 2);
|
|
95
|
+
writeFileSync(tempPath, json, "utf-8");
|
|
96
|
+
renameSync(tempPath, manifestPath);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
success: true,
|
|
100
|
+
manifest,
|
|
101
|
+
diagnostics: graph.diagnostics,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
diagnostics: [
|
|
109
|
+
{
|
|
110
|
+
severity: "error",
|
|
111
|
+
message: `Compilation error: ${message}`,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"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"}
|
package/dist/prose.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads all .prose files under root with default excludes
|
|
3
|
+
* @param root - Universe root directory
|
|
4
|
+
* @returns Array of prose file paths, sorted deterministically
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadProseFiles(root: string): Promise<string[]>;
|
|
7
|
+
//# sourceMappingURL=prose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prose.d.ts","sourceRoot":"","sources":["../src/prose.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASpE"}
|
package/dist/prose.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import fastGlob from "fast-glob";
|
|
3
|
+
const DEFAULT_EXCLUDES = [".sprig/**", "dist/**", "node_modules/**", ".git/**"];
|
|
4
|
+
/**
|
|
5
|
+
* Loads all .prose files under root with default excludes
|
|
6
|
+
* @param root - Universe root directory
|
|
7
|
+
* @returns Array of prose file paths, sorted deterministically
|
|
8
|
+
*/
|
|
9
|
+
export async function loadProseFiles(root) {
|
|
10
|
+
const pattern = join(root, "**/*.prose");
|
|
11
|
+
const allFiles = await fastGlob(pattern, {
|
|
12
|
+
absolute: true,
|
|
13
|
+
ignore: DEFAULT_EXCLUDES.map((exclude) => join(root, exclude)),
|
|
14
|
+
});
|
|
15
|
+
// Sort for deterministic ordering
|
|
16
|
+
return allFiles.sort();
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=prose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prose.js","sourceRoot":"","sources":["../src/prose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;AAEhF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE;QACvC,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;KAC/D,CAAC,CAAC;IAEH,kCAAkC;IAClC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
package/dist/root.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walks upward from startPath to find universe.prose marker
|
|
3
|
+
* @param startPath - Starting directory path
|
|
4
|
+
* @returns Path to directory containing universe.prose, or null if not found
|
|
5
|
+
*/
|
|
6
|
+
export declare function discoverUniverseRoot(startPath: string): string | null;
|
|
7
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../src/root.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBrE"}
|
package/dist/root.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
|
+
import { resolve, dirname, join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Walks upward from startPath to find universe.prose marker
|
|
5
|
+
* @param startPath - Starting directory path
|
|
6
|
+
* @returns Path to directory containing universe.prose, or null if not found
|
|
7
|
+
*/
|
|
8
|
+
export function discoverUniverseRoot(startPath) {
|
|
9
|
+
let current = resolve(startPath);
|
|
10
|
+
const root = resolve("/");
|
|
11
|
+
while (current !== root) {
|
|
12
|
+
const markerPath = join(current, "universe.prose");
|
|
13
|
+
if (existsSync(markerPath) && statSync(markerPath).isFile()) {
|
|
14
|
+
return current;
|
|
15
|
+
}
|
|
16
|
+
current = dirname(current);
|
|
17
|
+
}
|
|
18
|
+
// Check root directory as well
|
|
19
|
+
const rootMarkerPath = join(root, "universe.prose");
|
|
20
|
+
if (existsSync(rootMarkerPath) && statSync(rootMarkerPath).isFile()) {
|
|
21
|
+
return root;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=root.js.map
|
package/dist/root.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../src/root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1B,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC;QACxB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACnD,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5D,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,+BAA+B;IAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,cAAc,CAAC,IAAI,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/ui.d.ts
ADDED
package/dist/ui.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAiNA;;GAEG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE,MAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CAuHf"}
|