Compare commits
8 Commits
42daa49335
...
58d0b38ac9
| Author | SHA1 | Date | |
|---|---|---|---|
| 58d0b38ac9 | |||
| c20591d638 | |||
| 1ec3723c74 | |||
| f1f90976a5 | |||
| 060e3ecef6 | |||
| 3e328814f5 | |||
| 4b82ab30ff | |||
| 3d1e0bc204 |
99
README.md
99
README.md
@ -1 +1,100 @@
|
|||||||
# Prometeu Studio
|
# Prometeu Studio
|
||||||
|
|
||||||
|
Prometeu Studio is the desktop development environment for the Prometeu toolchain.
|
||||||
|
|
||||||
|
This repository packages the Studio shell together with the embedded services it depends on: project VFS, language tooling, compiler pipeline integration, and asset packing. The current implementation is a Java/JavaFX multi-module Gradle build.
|
||||||
|
|
||||||
|
## What Lives Here
|
||||||
|
|
||||||
|
The root project is a monorepo with these main areas:
|
||||||
|
|
||||||
|
- `prometeu-app`: JavaFX application entry point (`p.studio.App`).
|
||||||
|
- `prometeu-studio`: Studio UI, workspaces, project session lifecycle, play/stop flow, and debugger-facing surfaces.
|
||||||
|
- `prometeu-vfs`: project document access and save/open contracts.
|
||||||
|
- `prometeu-lsp`: language-service integration used by the editor workflow.
|
||||||
|
- `prometeu-packer`: embedded packer APIs and implementation used by Studio.
|
||||||
|
- `prometeu-compiler`: compiler core, build pipeline, frontend APIs, and the PBS frontend.
|
||||||
|
- `prometeu-infra`: shared infrastructure used across modules.
|
||||||
|
- `docs/`: normative specifications and architectural references.
|
||||||
|
- `discussion/`: workflow artifacts for agendas, decisions, plans, and lessons.
|
||||||
|
- `test-projects/`: sample workspaces used for local development and tests.
|
||||||
|
|
||||||
|
## Current Product Shape
|
||||||
|
|
||||||
|
The Studio shell currently organizes the product around four workspaces:
|
||||||
|
|
||||||
|
- Assets
|
||||||
|
- Code editor
|
||||||
|
- Debug
|
||||||
|
- Shipper
|
||||||
|
|
||||||
|
At runtime, the app boots an embedded packer, creates a project document VFS, wires LSP services, and opens the Studio launcher window. Project creation currently scaffolds a Prometeu workspace with `prometeu.json`, `src/`, `assets/`, `build/`, `cartridge/`, `.workspace/`, and local Studio metadata.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- JDK 21 or newer recommended for local development
|
||||||
|
- Gradle wrapper (`./gradlew`) included in the repository
|
||||||
|
- A desktop environment capable of running JavaFX
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
Run the full project graph listing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew projects
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the desktop application:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew :prometeu-app:run
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the test suite:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew test
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate the aggregated coverage report:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew jacocoTestReport
|
||||||
|
```
|
||||||
|
|
||||||
|
## Repository Reading Guide
|
||||||
|
|
||||||
|
If you are new to the codebase, this order is usually the fastest path:
|
||||||
|
|
||||||
|
1. Start at `prometeu-app` to see application bootstrap.
|
||||||
|
2. Read `prometeu-studio` for the shell, workspaces, and user-facing flows.
|
||||||
|
3. Read `prometeu-vfs`, `prometeu-lsp`, and `prometeu-packer` for service boundaries.
|
||||||
|
4. Read `prometeu-compiler` when you need compiler or PBS language behavior.
|
||||||
|
|
||||||
|
## Specs And Architecture
|
||||||
|
|
||||||
|
Important reference surfaces:
|
||||||
|
|
||||||
|
- `docs/specs/compiler/`: shared compiler specifications
|
||||||
|
- `docs/specs/packer/`: packer specifications
|
||||||
|
- `docs/vm-arch/`: VM and ISA architecture references
|
||||||
|
|
||||||
|
These documents are the long-term normative source for behavior and contracts. When code and docs diverge, fix the divergence explicitly instead of relying on tribal knowledge.
|
||||||
|
|
||||||
|
## Discussion Workflow
|
||||||
|
|
||||||
|
This repository uses a disciplined discussion workflow under `discussion/`:
|
||||||
|
|
||||||
|
- `discussion/workflow/agendas/`
|
||||||
|
- `discussion/workflow/decisions/`
|
||||||
|
- `discussion/workflow/plans/`
|
||||||
|
- `discussion/lessons/`
|
||||||
|
- `discussion/index.ndjson`
|
||||||
|
|
||||||
|
The expected execution flow is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
agenda -> decision -> plan -> implement -> lesson
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not create new workflow artifacts in legacy `docs/**/agendas`, `docs/**/decisions`, `docs/**/pull-requests`, or `docs/**/learn` paths.
|
||||||
|
|||||||
@ -8,6 +8,10 @@ import java.nio.file.Path;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public final class PackerRuntimeAssetMaterializer {
|
public final class PackerRuntimeAssetMaterializer {
|
||||||
|
private static final Set<String> RUNTIME_RESERVED_FILE_NAMES = Set.of(
|
||||||
|
"asset.json",
|
||||||
|
"studio.asset.json");
|
||||||
|
|
||||||
private final PackerAssetWalker assetWalker;
|
private final PackerAssetWalker assetWalker;
|
||||||
|
|
||||||
public PackerRuntimeAssetMaterializer(PackerAssetWalker assetWalker) {
|
public PackerRuntimeAssetMaterializer(PackerAssetWalker assetWalker) {
|
||||||
@ -114,7 +118,7 @@ public final class PackerRuntimeAssetMaterializer {
|
|||||||
private List<String> listAvailableFiles(Path assetRoot) {
|
private List<String> listAvailableFiles(Path assetRoot) {
|
||||||
try (var paths = Files.list(assetRoot)
|
try (var paths = Files.list(assetRoot)
|
||||||
.filter(Files::isRegularFile)
|
.filter(Files::isRegularFile)
|
||||||
.filter(path -> !path.getFileName().toString().equalsIgnoreCase("asset.json"))
|
.filter(path -> !isRuntimeReservedFile(path))
|
||||||
.map(path -> assetRoot.relativize(path.toAbsolutePath().normalize()).toString().replace('\\', '/'))
|
.map(path -> assetRoot.relativize(path.toAbsolutePath().normalize()).toString().replace('\\', '/'))
|
||||||
.sorted(String.CASE_INSENSITIVE_ORDER)) {
|
.sorted(String.CASE_INSENSITIVE_ORDER)) {
|
||||||
return paths.toList();
|
return paths.toList();
|
||||||
@ -123,6 +127,10 @@ public final class PackerRuntimeAssetMaterializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRuntimeReservedFile(Path path) {
|
||||||
|
return RUNTIME_RESERVED_FILE_NAMES.contains(path.getFileName().toString().toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
|
||||||
private PackerRuntimeWalkFile toRuntimeWalkFile(
|
private PackerRuntimeWalkFile toRuntimeWalkFile(
|
||||||
Path assetRoot,
|
Path assetRoot,
|
||||||
PackerProbeResult probeResult,
|
PackerProbeResult probeResult,
|
||||||
|
|||||||
@ -76,6 +76,7 @@ final class PackerRuntimeAssetMaterializerTest {
|
|||||||
final Path assetRoot = Files.createDirectories(tempDir.resolve("runtime-default"));
|
final Path assetRoot = Files.createDirectories(tempDir.resolve("runtime-default"));
|
||||||
final Path manifestPath = assetRoot.resolve("asset.json");
|
final Path manifestPath = assetRoot.resolve("asset.json");
|
||||||
Files.writeString(manifestPath, "{}");
|
Files.writeString(manifestPath, "{}");
|
||||||
|
Files.writeString(assetRoot.resolve("studio.asset.json"), "{}");
|
||||||
writeTile(assetRoot.resolve("selected.png"), 16);
|
writeTile(assetRoot.resolve("selected.png"), 16);
|
||||||
writeTile(assetRoot.resolve("extra.png"), 16);
|
writeTile(assetRoot.resolve("extra.png"), 16);
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ final class PackerRuntimeAssetMaterializerTest {
|
|||||||
Optional.empty());
|
Optional.empty());
|
||||||
|
|
||||||
assertEquals(2, materialized.runtimeAsset().walkProjection().buildCandidateFiles().size());
|
assertEquals(2, materialized.runtimeAsset().walkProjection().buildCandidateFiles().size());
|
||||||
|
assertEquals(List.of("extra.png", "selected.png"), materialized.runtimeAsset().walkProjection().availableFiles());
|
||||||
assertTrue(materialized.runtimeAsset().walkProjection().buildCandidateFiles().stream()
|
assertTrue(materialized.runtimeAsset().walkProjection().buildCandidateFiles().stream()
|
||||||
.allMatch(file -> file.contentBytes().isEmpty()));
|
.allMatch(file -> file.contentBytes().isEmpty()));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user