Add EveElectron semantic capture artifact
This commit is contained in:
parent
595ce6fbf4
commit
3f7e381ea8
10 changed files with 292 additions and 20 deletions
|
|
@ -490,9 +490,12 @@ Recently cut:
|
|||
`tools/eveelectron/eveelectron-release-contract.mjs` and
|
||||
`scripts/run-eveelectron-release-contract-smoke.ps1`; capture uses
|
||||
`tools/eveelectron/eveelectron-capture-contract.mjs` and
|
||||
`scripts/run-eveelectron-capture-contract-smoke.ps1`. The packaged Electron
|
||||
app, packaged window rendering, and actual Electron window capture artifacts
|
||||
remain pending EveElectron work.
|
||||
`scripts/run-eveelectron-capture-contract-smoke.ps1`, plus a deterministic
|
||||
`gamecult.eve.electron_shell_projection.v1` JSON projection artifact through
|
||||
`tools/eveelectron/eveelectron-capture-artifact.mjs` and
|
||||
`scripts/run-eveelectron-capture-smoke.ps1`. The packaged Electron app,
|
||||
packaged window rendering, and actual Electron window PNG artifacts remain
|
||||
pending EveElectron work.
|
||||
- Electron pending lifecycle details and TUI active-incubation lifecycle details
|
||||
now live in their runtime capability manifests rather than being duplicated in
|
||||
`tools/parity/parity-manifest.json`. The parity ledger points at the
|
||||
|
|
@ -575,9 +578,12 @@ Recently cut:
|
|||
authority rule. `tools/eveelectron/eveelectron-capture-contract.mjs` builds a
|
||||
`gamecult.eve.runtime_capture_request.v1` request from the runtime capability
|
||||
manifest and provider advertisement, and
|
||||
`scripts/run-eveelectron-capture-contract-smoke.ps1` proves that request path
|
||||
without pretending an Electron window PNG has been captured. The actual
|
||||
capture artifact remains a split blocker for EveElectron.
|
||||
`scripts/run-eveelectron-capture-contract-smoke.ps1` proves that request path.
|
||||
`tools/eveelectron/eveelectron-capture-artifact.mjs` now also lowers the
|
||||
Aetheria world surface through `EveElectronShell`, writes
|
||||
`artifacts/eveelectron-capture/latest/electron-shell-projection.json`, and
|
||||
exports it as `runtime.captureArtifacts[]`. The actual packaged window PNG
|
||||
remains a split blocker for EveElectron.
|
||||
- EveTui capture lifecycle now attaches a typed terminal-grid artifact instead
|
||||
of stopping at a request contract. `tools/evetui/evetui-capture-artifact.mjs`
|
||||
lowers `web/fixtures/aetheria-world-surface.json` through `EveTuiShell`,
|
||||
|
|
|
|||
|
|
@ -325,9 +325,9 @@ Electron source paths named by the handoff currently exist as
|
|||
`observed-provider` sources, so the extraction pressure is visible without
|
||||
turning those paths into EveElectron authority. The Electron runtime now claims
|
||||
a narrow provider-advertised surface-tree command surface and exposes a typed
|
||||
capture request contract. It preserves embedded document slot identity in the
|
||||
generic shell projection, while packaged rendering, actual window capture, and
|
||||
plugin projection remain blockers.
|
||||
capture request contract plus a schema-backed JSON shell projection artifact.
|
||||
It preserves embedded document slot identity in the generic shell projection,
|
||||
while packaged rendering and actual window PNG capture remain blockers.
|
||||
EveTui is now an active incubating runtime: it claims a lossy
|
||||
provider-advertised terminal-grid command surface, preserves embedded document
|
||||
slot identity in the grid artifact, projects Sai/Norn/TeX fallback shells, and
|
||||
|
|
@ -404,6 +404,13 @@ it without depending on Eve's source layout. The remaining blocker is
|
|||
owner-repo production of the same capture path, not absence of a cell-grid
|
||||
artifact.
|
||||
|
||||
Electron semantic capture evidence follows the same evidence rule without
|
||||
pretending it is a packaged window PNG. `tools/eveelectron/eveelectron-capture-artifact.mjs`
|
||||
lowers the Aetheria world surface through `EveElectronShell` into
|
||||
`gamecult.eve.electron_shell_projection.v1` and writes
|
||||
`artifacts/eveelectron-capture/latest/electron-shell-projection.json`. The
|
||||
remaining blocker is packaged Electron window capture.
|
||||
|
||||
EveUnity split handoff evidence:
|
||||
|
||||
```powershell
|
||||
|
|
|
|||
|
|
@ -149,7 +149,10 @@
|
|||
"evidencePaths": [
|
||||
"tools/eveelectron/eveelectron-capture-contract.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-contract.test.mjs",
|
||||
"scripts/run-eveelectron-capture-contract-smoke.ps1"
|
||||
"tools/eveelectron/eveelectron-capture-artifact.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-artifact.test.mjs",
|
||||
"scripts/run-eveelectron-capture-contract-smoke.ps1",
|
||||
"scripts/run-eveelectron-capture-smoke.ps1"
|
||||
],
|
||||
"pendingProofs": [
|
||||
"Electron window capture artifact is attached to the runtime conformance report."
|
||||
|
|
@ -157,7 +160,19 @@
|
|||
}
|
||||
},
|
||||
"capture": {
|
||||
"status": "missing",
|
||||
"note": "Electron capture is a split blocker until EveElectron attaches provider-agnostic shell window artifacts."
|
||||
"status": "json-projection",
|
||||
"note": "Electron attaches a provider-advertisement-backed gamecult.eve.electron_shell_projection.v1 JSON projection artifact; packaged window PNG capture remains an EveElectron split blocker.",
|
||||
"artifacts": [
|
||||
{
|
||||
"kind": "json-projection",
|
||||
"schema": "gamecult.eve.electron_shell_projection.v1",
|
||||
"path": "artifacts/eveelectron-capture/latest/electron-shell-projection.json",
|
||||
"runtimeId": "electron-shell",
|
||||
"providerId": "aetheria",
|
||||
"surfaceId": "aetheria.daemon.game",
|
||||
"sourceSurfacePath": "web/fixtures/aetheria-world-surface.json",
|
||||
"requestPath": "artifacts/eveelectron-capture/latest/capture-request.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,10 +73,13 @@
|
|||
"currentPaths": [
|
||||
"tools/eveelectron/eveelectron-capture-contract.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-contract.test.mjs",
|
||||
"scripts/run-eveelectron-capture-contract-smoke.ps1"
|
||||
"tools/eveelectron/eveelectron-capture-artifact.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-artifact.test.mjs",
|
||||
"scripts/run-eveelectron-capture-contract-smoke.ps1",
|
||||
"scripts/run-eveelectron-capture-smoke.ps1"
|
||||
],
|
||||
"destinationOwner": "EveElectron",
|
||||
"replacementProof": "EveElectron builds a provider-advertisement-backed capture request now; the split is not complete until the EveElectron repo attaches desktop-window capture artifacts to conformance output for at least one non-Aetheria provider and one Aetheria scenario."
|
||||
"replacementProof": "EveElectron builds a provider-advertisement-backed capture request and deterministic gamecult.eve.electron_shell_projection.v1 JSON projection artifact now; the split is not complete until the EveElectron repo attaches desktop-window capture artifacts to conformance output for at least one non-Aetheria provider and one Aetheria scenario."
|
||||
}
|
||||
],
|
||||
"contractInputs": [
|
||||
|
|
@ -103,6 +106,6 @@
|
|||
"EveElectron lowers at least one generic Eve provider surface that is not Aetheria.",
|
||||
"EveElectron lowers Aetheria world/editor surfaces through provider advertisements without importing Aetheria internals.",
|
||||
"Aetheria keeps Starbridge-specific UI, assets, authored flows, and receipts in the Aetheria repo.",
|
||||
"EveElectron attaches Electron capture artifacts to conformance output."
|
||||
"EveElectron attaches packaged Electron window PNG capture artifacts to conformance output."
|
||||
]
|
||||
}
|
||||
|
|
|
|||
73
scripts/run-eveelectron-capture-smoke.ps1
Normal file
73
scripts/run-eveelectron-capture-smoke.ps1
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
param(
|
||||
[string] $CapabilityManifestPath = "runtimes\incubating\eve-electron\eve-runtime-capability.json",
|
||||
[string] $AdvertisementPath = "web\fixtures\aetheria.provider-advertisement.json",
|
||||
[string] $SurfacePath = "web\fixtures\aetheria-world-surface.json",
|
||||
[string] $OutputPath = "artifacts\eveelectron-capture\latest\electron-shell-projection.json",
|
||||
[string] $RequestOutputPath = "artifacts\eveelectron-capture\latest\capture-request.json",
|
||||
[string] $Stamp = "latest"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$projectRoot = Split-Path -Parent $PSScriptRoot
|
||||
function Resolve-RepoPath([string] $candidate) {
|
||||
if ([System.IO.Path]::IsPathRooted($candidate)) {
|
||||
return $candidate
|
||||
}
|
||||
return Join-Path $projectRoot $candidate
|
||||
}
|
||||
|
||||
$absoluteCapabilityPath = Resolve-RepoPath $CapabilityManifestPath
|
||||
$absoluteAdvertisementPath = Resolve-RepoPath $AdvertisementPath
|
||||
$absoluteSurfacePath = Resolve-RepoPath $SurfacePath
|
||||
$absoluteOutputPath = Resolve-RepoPath $OutputPath
|
||||
$absoluteRequestOutputPath = Resolve-RepoPath $RequestOutputPath
|
||||
|
||||
foreach ($path in @($absoluteCapabilityPath, $absoluteAdvertisementPath, $absoluteSurfacePath)) {
|
||||
if (-not (Test-Path -LiteralPath $path)) {
|
||||
throw "EveElectron capture input not found: $path"
|
||||
}
|
||||
}
|
||||
|
||||
node --test (Join-Path $projectRoot "tools\eveelectron\eveelectron-capture-artifact.test.mjs")
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "EveElectron capture artifact tests failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
node (Join-Path $projectRoot "tools\eveelectron\eveelectron-capture-artifact.mjs") `
|
||||
--capability $absoluteCapabilityPath `
|
||||
--advertisement $absoluteAdvertisementPath `
|
||||
--surface $absoluteSurfacePath `
|
||||
--output $absoluteOutputPath `
|
||||
--request-output $absoluteRequestOutputPath `
|
||||
--stamp $Stamp
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "EveElectron capture artifact builder failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
foreach ($path in @($absoluteOutputPath, $absoluteRequestOutputPath)) {
|
||||
if (-not (Test-Path -LiteralPath $path)) {
|
||||
throw "EveElectron capture artifact output missing: $path"
|
||||
}
|
||||
}
|
||||
|
||||
$projection = Get-Content -LiteralPath $absoluteOutputPath -Raw | ConvertFrom-Json
|
||||
foreach ($expectation in @(
|
||||
@{ field = "schema"; value = "gamecult.eve.electron_shell_projection.v1" },
|
||||
@{ field = "runtimeId"; value = "electron-shell" },
|
||||
@{ field = "providerId"; value = "aetheria" },
|
||||
@{ field = "surfaceId"; value = "aetheria.daemon.game" },
|
||||
@{ field = "commandBoundary"; value = "aetheria.daemon.commands" },
|
||||
@{ field = "receiptSchema"; value = "aetheria.eve_command_acceptance_status.v1" },
|
||||
@{ field = "artifactKind"; value = "json-projection" },
|
||||
@{ field = "captureKind"; value = "electron-shell-projection-json" }
|
||||
)) {
|
||||
if ($projection.($expectation.field) -ne $expectation.value) {
|
||||
throw "EveElectron projection $($expectation.field) expected $($expectation.value) got $($projection.($expectation.field))"
|
||||
}
|
||||
}
|
||||
if (-not $projection.root.id) {
|
||||
throw "EveElectron projection capture must contain a root shell node"
|
||||
}
|
||||
|
||||
Write-Host "EveElectron capture smoke passed: $absoluteOutputPath"
|
||||
|
|
@ -194,5 +194,6 @@ foreach ($pathProperty in @("requestBuilder", "advertisementPath")) {
|
|||
& (Join-Path $projectRoot "scripts\run-eveelectron-release-contract-smoke.ps1")
|
||||
& (Join-Path $projectRoot "scripts\run-eveelectron-provider-shell-smoke.ps1")
|
||||
& (Join-Path $projectRoot "scripts\run-eveelectron-capture-contract-smoke.ps1")
|
||||
& (Join-Path $projectRoot "scripts\run-eveelectron-capture-smoke.ps1")
|
||||
|
||||
Write-Host "EveElectron lifecycle smoke passed: $absoluteManifestPath"
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ node $consumerScript $consumerExport `
|
|||
--expect-runtime-capture-status android-flutter:adb-png `
|
||||
--expect-runtime-capture-status unity-uitoolkit:semantic `
|
||||
--expect-runtime-capture-status unity-scene:missing `
|
||||
--expect-runtime-capture-status electron-shell:missing `
|
||||
--expect-runtime-capture-status electron-shell:json-projection `
|
||||
--expect-runtime-capture-artifact electron-shell:json-projection:gamecult.eve.electron_shell_projection.v1:aetheria:aetheria.daemon.game `
|
||||
--expect-runtime-capture-status tui:json-grid `
|
||||
--expect-runtime-capture-artifact tui:json-grid:gamecult.eve.tui_grid.v1:aetheria:aetheria.daemon.game `
|
||||
--expect-runtime-capture-status direct2d:missing `
|
||||
|
|
|
|||
113
tools/eveelectron/eveelectron-capture-artifact.mjs
Normal file
113
tools/eveelectron/eveelectron-capture-artifact.mjs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import { mkdirSync, writeFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { EveElectronShell } from "../../runtimes/incubating/eve-electron/src/eve-electron-shell.mjs";
|
||||
import { buildElectronCaptureRequest, loadJsonFile, writeCaptureRequest } from "./eveelectron-capture-contract.mjs";
|
||||
|
||||
export function buildElectronCaptureArtifact({
|
||||
advertisement,
|
||||
capabilityManifest,
|
||||
surfaceDocument,
|
||||
advertisementPath = "",
|
||||
capabilityManifestPath = "",
|
||||
stamp = "latest",
|
||||
} = {}) {
|
||||
const request = buildElectronCaptureRequest({
|
||||
advertisement,
|
||||
capabilityManifest,
|
||||
advertisementPath,
|
||||
capabilityManifestPath,
|
||||
stamp,
|
||||
});
|
||||
const shell = new EveElectronShell();
|
||||
const projection = shell.lowerSurface(surfaceDocument, advertisement, request.surfaceId);
|
||||
validateProjectionArtifact(projection, request);
|
||||
|
||||
return {
|
||||
request,
|
||||
projection: {
|
||||
...projection,
|
||||
runtimeId: request.runtimeId,
|
||||
artifactKind: "json-projection",
|
||||
captureKind: "electron-shell-projection-json",
|
||||
sourceAdvertisementPath: request.sourceAdvertisementPath,
|
||||
sourceCapabilityManifestPath: request.sourceCapabilityManifestPath,
|
||||
issuedAtUtc: request.issuedAtUtc,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function writeElectronCaptureArtifact({ request, projection }, { outputPath, requestOutputPath = "" } = {}) {
|
||||
if (!outputPath) throw new Error("outputPath is required");
|
||||
mkdirSync(path.dirname(outputPath), { recursive: true });
|
||||
writeFileSync(outputPath, `${JSON.stringify(projection, null, 2)}\n`, "utf8");
|
||||
if (requestOutputPath) {
|
||||
writeCaptureRequest(request, requestOutputPath);
|
||||
}
|
||||
}
|
||||
|
||||
function validateProjectionArtifact(projection, request) {
|
||||
if (projection.schema !== "gamecult.eve.electron_shell_projection.v1") {
|
||||
throw new Error(`Unexpected Electron projection schema: ${projection.schema || ""}`);
|
||||
}
|
||||
for (const [field, expected] of [
|
||||
["providerId", request.providerId],
|
||||
["surfaceId", request.surfaceId],
|
||||
["projectionKind", request.projectionKind],
|
||||
["commandBoundary", request.commandBoundary],
|
||||
["receiptSchema", request.receiptSchema],
|
||||
]) {
|
||||
if ((projection[field] || "") !== (expected || "")) {
|
||||
throw new Error(`Electron projection ${field} expected ${expected || ""} got ${projection[field] || ""}`);
|
||||
}
|
||||
}
|
||||
if (!projection.root || !projection.root.id) {
|
||||
throw new Error("Electron projection artifact must contain a root shell node");
|
||||
}
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = {};
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const value = argv[index];
|
||||
if (!value.startsWith("--")) continue;
|
||||
const key = value.slice(2);
|
||||
const next = argv[index + 1];
|
||||
if (!next || next.startsWith("--")) {
|
||||
args[key] = true;
|
||||
} else {
|
||||
args[key] = next;
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
function runCli() {
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
for (const required of ["advertisement", "capability", "surface", "output"]) {
|
||||
if (!args[required]) {
|
||||
throw new Error(`missing required --${required}`);
|
||||
}
|
||||
}
|
||||
const stamp = args.stamp || "latest";
|
||||
const artifact = buildElectronCaptureArtifact({
|
||||
advertisement: loadJsonFile(args.advertisement),
|
||||
capabilityManifest: loadJsonFile(args.capability),
|
||||
surfaceDocument: loadJsonFile(args.surface),
|
||||
advertisementPath: args.advertisement,
|
||||
capabilityManifestPath: args.capability,
|
||||
stamp,
|
||||
});
|
||||
writeElectronCaptureArtifact(artifact, {
|
||||
outputPath: args.output,
|
||||
requestOutputPath: args["request-output"] || "",
|
||||
});
|
||||
process.stdout.write(`${args.output}\n`);
|
||||
}
|
||||
|
||||
const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : "";
|
||||
const modulePath = fileURLToPath(import.meta.url);
|
||||
if (invokedPath === modulePath) {
|
||||
runCli();
|
||||
}
|
||||
30
tools/eveelectron/eveelectron-capture-artifact.test.mjs
Normal file
30
tools/eveelectron/eveelectron-capture-artifact.test.mjs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
import { buildElectronCaptureArtifact } from "./eveelectron-capture-artifact.mjs";
|
||||
|
||||
const advertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
|
||||
const capabilityManifest = JSON.parse(readFileSync(new URL("../../runtimes/incubating/eve-electron/eve-runtime-capability.json", import.meta.url), "utf8"));
|
||||
const surfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria-world-surface.json", import.meta.url), "utf8"));
|
||||
|
||||
test("builds Electron shell projection capture artifact from provider advertisement and surface", () => {
|
||||
const { request, projection } = buildElectronCaptureArtifact({
|
||||
advertisement,
|
||||
capabilityManifest,
|
||||
surfaceDocument,
|
||||
advertisementPath: "web/fixtures/aetheria.provider-advertisement.json",
|
||||
capabilityManifestPath: "runtimes/incubating/eve-electron/eve-runtime-capability.json",
|
||||
stamp: "smoke",
|
||||
});
|
||||
|
||||
assert.equal(request.artifactPath, "artifacts/eveelectron-capture/smoke/electron-shell.png");
|
||||
assert.equal(projection.schema, "gamecult.eve.electron_shell_projection.v1");
|
||||
assert.equal(projection.runtimeId, "electron-shell");
|
||||
assert.equal(projection.providerId, "aetheria");
|
||||
assert.equal(projection.surfaceId, "aetheria.daemon.game");
|
||||
assert.equal(projection.commandBoundary, "aetheria.daemon.commands");
|
||||
assert.equal(projection.receiptSchema, "aetheria.eve_command_acceptance_status.v1");
|
||||
assert.equal(projection.artifactKind, "json-projection");
|
||||
assert.equal(projection.captureKind, "electron-shell-projection-json");
|
||||
assert.equal(projection.root.id, "aetheria.daemon.game.root");
|
||||
});
|
||||
|
|
@ -676,7 +676,7 @@
|
|||
"pendingProofs": [
|
||||
"Electron shell runtime body graduates to EveElectron outside Aetheria product code.",
|
||||
"Electron renders embedded Eve documents in a packaged Electron window.",
|
||||
"Electron capture artifacts are attached to conformance output."
|
||||
"Electron packaged window PNG capture artifacts are attached to conformance output."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -782,10 +782,13 @@
|
|||
"scripts/run-eveelectron-provider-shell-smoke.ps1",
|
||||
"scripts/run-eveelectron-release-contract-smoke.ps1",
|
||||
"scripts/run-eveelectron-capture-contract-smoke.ps1",
|
||||
"scripts/run-eveelectron-capture-smoke.ps1",
|
||||
"tools/eveelectron/eveelectron-release-contract.mjs",
|
||||
"tools/eveelectron/eveelectron-release-contract.test.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-contract.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-contract.test.mjs"
|
||||
"tools/eveelectron/eveelectron-capture-contract.test.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-artifact.mjs",
|
||||
"tools/eveelectron/eveelectron-capture-artifact.test.mjs"
|
||||
],
|
||||
"expectedSourceSymbols": [
|
||||
{
|
||||
|
|
@ -804,6 +807,14 @@
|
|||
"path": "tools/eveelectron/eveelectron-capture-contract.test.mjs",
|
||||
"contains": ["builds Electron shell capture request from provider advertisement", "rejects capture request when the surface does not advertise Electron shell", "electron-shell", "aetheria.daemon.commands"]
|
||||
},
|
||||
{
|
||||
"path": "tools/eveelectron/eveelectron-capture-artifact.mjs",
|
||||
"contains": ["buildElectronCaptureArtifact", "EveElectronShell", "gamecult.eve.electron_shell_projection.v1", "json-projection", "writeElectronCaptureArtifact", "request-output"]
|
||||
},
|
||||
{
|
||||
"path": "tools/eveelectron/eveelectron-capture-artifact.test.mjs",
|
||||
"contains": ["builds Electron shell projection capture artifact", "gamecult.eve.electron_shell_projection.v1", "electron-shell-projection-json"]
|
||||
},
|
||||
{
|
||||
"path": "tools/eveelectron/eveelectron-release-contract.mjs",
|
||||
"contains": ["buildElectronReleaseRequest", "gamecult.eve.runtime_release_request.v1", "eveelectron-release", "writeReleaseRequest"]
|
||||
|
|
@ -814,8 +825,20 @@
|
|||
}
|
||||
],
|
||||
"capture": {
|
||||
"status": "missing",
|
||||
"note": "Electron capture is a split blocker until EveElectron attaches provider-agnostic shell window artifacts."
|
||||
"status": "json-projection",
|
||||
"note": "Electron attaches a provider-advertisement-backed gamecult.eve.electron_shell_projection.v1 JSON projection artifact; packaged window PNG capture remains an EveElectron split blocker.",
|
||||
"artifacts": [
|
||||
{
|
||||
"kind": "json-projection",
|
||||
"schema": "gamecult.eve.electron_shell_projection.v1",
|
||||
"path": "artifacts/eveelectron-capture/latest/electron-shell-projection.json",
|
||||
"runtimeId": "electron-shell",
|
||||
"providerId": "aetheria",
|
||||
"surfaceId": "aetheria.daemon.game",
|
||||
"sourceSurfacePath": "web/fixtures/aetheria-world-surface.json",
|
||||
"requestPath": "artifacts/eveelectron-capture/latest/capture-request.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue