@hyprune/schema 0.0.0-stage → 0.5.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.
- package/CHANGELOG.md +144 -0
- package/LICENSE +21 -0
- package/README.md +140 -2
- package/bin/validate.mjs +19 -0
- package/examples/extension.json +22 -0
- package/examples/ipc/error.json +11 -0
- package/examples/ipc/movement.set.request.json +8 -0
- package/examples/ipc/movement.set.response.json +7 -0
- package/examples/ipc/runtime.exit.request.json +6 -0
- package/examples/ipc/runtime.exit.response.json +7 -0
- package/examples/ipc/runtime.notice.notification.json +9 -0
- package/examples/ipc/session.hello.request.json +17 -0
- package/examples/ipc/session.hello.response.json +23 -0
- package/examples/ipc/session.ping.request.json +6 -0
- package/examples/ipc/session.ping.response.json +7 -0
- package/examples/ipc/session.revoked.notification.json +7 -0
- package/examples/ipc/shell.claim.request.json +10 -0
- package/examples/ipc/shell.claim.response.json +8 -0
- package/examples/ipc/shell.overlay.request.json +11 -0
- package/examples/ipc/shell.overlay.response.json +7 -0
- package/examples/ipc/shell.release.request.json +8 -0
- package/examples/ipc/shell.release.response.json +7 -0
- package/examples/ipc/state.delta.notification.json +18 -0
- package/examples/ipc/state.snapshot.request.json +8 -0
- package/examples/ipc/state.snapshot.response.json +37 -0
- package/examples/ipc/state.subscribe.request.json +10 -0
- package/examples/ipc/state.subscribe.response.json +38 -0
- package/examples/ipc/state.unsubscribe.request.json +8 -0
- package/examples/ipc/state.unsubscribe.response.json +7 -0
- package/examples/ipc/surface.focus.request.json +9 -0
- package/examples/ipc/surface.focus.response.json +7 -0
- package/examples/ipc/world.load.request.json +9 -0
- package/examples/ipc/world.load.response.json +7 -0
- package/examples/placement-input.json +169 -0
- package/examples/screen-type.json +24 -0
- package/examples/world.json +111 -0
- package/extensions/hud-style-manifest.schema.json +17 -0
- package/extensions/hud-style.schema.json +118 -0
- package/lib/validate.d.mts +37 -0
- package/lib/validate.mjs +221 -0
- package/package.json +57 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## v0 / 0.1.0 — 2026-10-07 (proposed)
|
|
5
|
+
|
|
6
|
+
Initial JSON Schema 2020-12 family: world format `0.1`, IPC `0.1`, extension manifest/API `0.1`, screen descriptor `0.1`. Includes every core method's request and result plus notifications, offline examples and a Node validator. Identifiers are reserved for these contracts; incompatible changes require a new wire/format identifier and migration notes. No runtime compatibility is claimed yet.
|
|
7
|
+
|
|
8
|
+
## 0.2.0 — 2026-10-07
|
|
9
|
+
|
|
10
|
+
Adds frozen `v0.2/` schemas for IPC 0.2 and world format 0.2; `v0/` stays unchanged. The validator accepts an optional fourth `version` argument (default `0.1`); CLI accepts `[response-method|-] [contract-version]`.
|
|
11
|
+
|
|
12
|
+
IPC adds camera get/set, waypoint/route, travel, autodrive, ui.open/close, data.publish/remove and presentation notifications. `location` and `integrations` are revisioned state keys. Publishing requires its own capability; scalar values, TTL, sequence and ownership are specified by RFC-0003. World 0.2 has the same manifest shape, with RFC-0004's sampler/transform/PBR material semantics. No mock-only protocol is accepted.
|
|
13
|
+
|
|
14
|
+
M1 shell reconciliation adds stable transition IDs, output identity, monotonic timestamps and indeterminate loading/failed phases. World-load destinations remain distinct from point/zone navigation targets.
|
|
15
|
+
|
|
16
|
+
## 0.3.0 — first real session
|
|
17
|
+
|
|
18
|
+
Frozen IPC 0.3 adds verified shell Wayland-child binding, workspace activation,
|
|
19
|
+
revisioned safe inline map/metadata, selected-output descriptor and core-projected
|
|
20
|
+
markers. 0.1/0.2 and world formats remain frozen. New positive/negative tests cover
|
|
21
|
+
version isolation, reserved parameters, PID/workspace bounds and marker clipping.
|
|
22
|
+
|
|
23
|
+
## 0.4.0 (M2)
|
|
24
|
+
|
|
25
|
+
- World format 0.3: workspace homes, typed mounts/frames/limits, reserved placement
|
|
26
|
+
volumes, camera-relative atmosphere, HDR bloom/exposure and static sky IBL.
|
|
27
|
+
- IPC 0.4: workspace bindings/focus, pull/place/return/recall, durable placement
|
|
28
|
+
rules, data-object bindings, atmosphere and FOV. Older wire contracts stay frozen.
|
|
29
|
+
- Added independent ownership/interaction/limits and version-isolation tests.
|
|
30
|
+
|
|
31
|
+
## 0.5.0 (M3A)
|
|
32
|
+
|
|
33
|
+
Frozen IPC 0.5 adds revisioned interaction mode/tool state, workspace app metadata,
|
|
34
|
+
and custom surface pose/size placement rules. All prior schemas stay unchanged;
|
|
35
|
+
world format remains 0.3. Tests cover exact version isolation, closed objects,
|
|
36
|
+
bounded app/tool collections and complete custom placement records.
|
|
37
|
+
|
|
38
|
+
IPC 0.6 (M3B): independent input keymap v2, three variants per action, core-owned validated persistence and lease-bound capture; closed keymap/editor state, per-area paths and object transforms, scope FOV down to 3 degrees, Map opening intent. Older contracts remain byte-identical.
|
|
39
|
+
|
|
40
|
+
IPC 0.7 publishes the exact shell graphics handoff: discoverable presets/effects,
|
|
41
|
+
validated sparse `graphics.set`, effective settings and asynchronous GPU timings.
|
|
42
|
+
IPC 0.8 adds `keymap.holds` (monotonic start time and configured duration) for
|
|
43
|
+
shell-owned hold animation. Protocols through 0.7 retain their exact shapes;
|
|
44
|
+
world format remains 0.3. No compositor config reload is involved.
|
|
45
|
+
|
|
46
|
+
## Climbing: world 0.4 and IPC 0.11
|
|
47
|
+
|
|
48
|
+
World 0.4 adds validated oriented climbable segments, climb-face normals,
|
|
49
|
+
feet-position exits, material type and optional speed. Runtime validates capsule
|
|
50
|
+
clearance against world collision. IPC 0.11 adds version-isolated movement
|
|
51
|
+
activity, ladder identity and interaction prompt fields. Previous versions stay
|
|
52
|
+
unchanged. See `test/climbing.test.mjs` and RFC-0004/0006.
|
|
53
|
+
|
|
54
|
+
## IPC 0.12 — deterministic input and camera recordings
|
|
55
|
+
|
|
56
|
+
Extends frozen IPC 0.11 (climbing) with input.control-gated recording.start/stop/
|
|
57
|
+
mark/status and replay.start/stop/status, bounded assertion specs, and the
|
|
58
|
+
unbound record.toggle action in every input mode. Older keymaps are projected
|
|
59
|
+
without that action. Runtime records are private, versioned JSONL, with app
|
|
60
|
+
keystrokes masked by default. Replay uses a fixed 60 Hz clock; camera-only
|
|
61
|
+
replay never forwards input. Existing 0.11 movement activity remains inherited.
|
|
62
|
+
|
|
63
|
+
## IPC 0.13 and world 0.5 — generic authoring and rendering controls
|
|
64
|
+
|
|
65
|
+
- Capability-gated photo-camera hold with normalized quaternion, 5–140° vertical
|
|
66
|
+
FOV, NDC lens shift and fixed render scale; camera.get reports actual lens state.
|
|
67
|
+
- Optional authored depth/normal ink style and Performance override/cost.
|
|
68
|
+
- Explicit visibility areas with bounds, scene-node subtrees and visibleFrom
|
|
69
|
+
lists. Unassigned geometry and cameras outside areas remain visible.
|
|
70
|
+
- Prior world and IPC schemas are unchanged; positive/negative tests cover the
|
|
71
|
+
new bounds, links, ownership and closed fields.
|
|
72
|
+
|
|
73
|
+
## IPC 0.15 — tool slots, pocket queue and content sizing
|
|
74
|
+
|
|
75
|
+
Adds generic tool declarations, bounded pocket/client feedback, canonical shared
|
|
76
|
+
Primary/Secondary/Alternate/Cycle bindings and optional persistent placement
|
|
77
|
+
content dimensions. Earlier IPC schemas stay byte-for-byte frozen. World format
|
|
78
|
+
is unchanged (0.5).
|
|
79
|
+
|
|
80
|
+
## World 0.7 — 2026-10-09
|
|
81
|
+
|
|
82
|
+
`v0.7/world.schema.json` (world.json shape as 0.6, `formatVersion: "0.7"`) and
|
|
83
|
+
`v0.7/common.schema.json` (0.6 definitions). New `scene` validation kind checks a
|
|
84
|
+
package's `scene.gltf` against its world format: 0.7 may require
|
|
85
|
+
`KHR_texture_basisu` (KTX2 material textures), `EXT_meshopt_compression` and
|
|
86
|
+
`KHR_mesh_quantization`, and must list those it uses in `extensionsRequired`;
|
|
87
|
+
lightmap textures stay PNG in every v0 format. Exports `atLeast()`,
|
|
88
|
+
`worldFormats` and `sceneExtensions()` so version gates are not hard-coded lists.
|
|
89
|
+
Inheritance test: every valid 0.6 document is valid as 0.7. IPC is unchanged.
|
|
90
|
+
|
|
91
|
+
## IPC 0.16 — 2026-10-10
|
|
92
|
+
|
|
93
|
+
`v0.16/ipc.schema.json`: graphics `upscaler` setting (`fsr1` | `bilinear` |
|
|
94
|
+
null) in config, effective values, overrides, presets and `graphics.set`
|
|
95
|
+
patches; `session.hello` reports `0.16`. Inheritance test: every 0.15
|
|
96
|
+
definition exists in 0.16 and the graphics properties differ only by the new key.
|
|
97
|
+
|
|
98
|
+
## IPC 0.17: debug capture notes
|
|
99
|
+
|
|
100
|
+
- `capture.annotate {captureId, note}` (shell.control): writes an optional note
|
|
101
|
+
(0..1000 code points, no control characters) into a debug capture's JSON and
|
|
102
|
+
the captures index. Result `{revision}`.
|
|
103
|
+
- `capture.taken {captureId, timestampMs, mode}` notification, sent to 0.17
|
|
104
|
+
shells when U (or the mode's capture binding) snapshots the world, before the
|
|
105
|
+
files are written.
|
|
106
|
+
- Everything else is inherited from 0.16 unchanged.
|
|
107
|
+
|
|
108
|
+
## IPC 0.18: device-scaled offload power cap and offload device selection
|
|
109
|
+
|
|
110
|
+
- `offload_power_cap_w` in `graphicsConfig`/`graphicsPatch` is a number 20–1000
|
|
111
|
+
or `null` (was 20–100). `null`, the new default, is automatic: the battery
|
|
112
|
+
profile ceiling with a battery, otherwise 75 % of the offload GPU's enforced
|
|
113
|
+
power limit (80 W when the limit is unknown).
|
|
114
|
+
- New `offload_device`: `"auto"` (default) or the lowercase PCI address
|
|
115
|
+
(`domain:bus:device.function`, e.g. `0000:65:00.0`) of the GPU that runs the
|
|
116
|
+
offload renderer.
|
|
117
|
+
- `performance` (graphics.get/set) gains required `capSource` (`profile` |
|
|
118
|
+
`device` | `configured` | `fallback`) and `device` (`null` or `{pci, node,
|
|
119
|
+
name, enforcedLimitW, selection, drivesCompositor}`). `profile` is unchanged;
|
|
120
|
+
systems without a battery report `full-ac`.
|
|
121
|
+
- `session.hello` reports `0.18`. Everything else is inherited from 0.17
|
|
122
|
+
unchanged. Inheritance test: every 0.17 definition is identical except the
|
|
123
|
+
graphics properties (only the two offload keys differ), `performance` (only
|
|
124
|
+
the two new keys) and the hello protocol constant.
|
|
125
|
+
|
|
126
|
+
## IPC 0.19: player settings, view bob and reticle
|
|
127
|
+
|
|
128
|
+
- `player.get {}` (state.read) and `player.set {patch}` (movement.control) return
|
|
129
|
+
`playerSettings {config, defaults, overrides, options, ranges, path, error}`.
|
|
130
|
+
`playerConfig` keys: `walk_speed`, `run_speed`, `view_bob`
|
|
131
|
+
(`off|subtle|normal`), `reticle_style`, `reticle_size`, `reticle_thickness`,
|
|
132
|
+
`reticle_gap`, `reticle_opacity`, `reticle_outline`, `reticle_colour`
|
|
133
|
+
(`"theme"` or RGB), `reticle_dynamic`, `reach_grab`, `reach_mount`,
|
|
134
|
+
`reach_placement`. `playerPatch` takes any subset (at least one key); `null`
|
|
135
|
+
removes a persisted override. `overrides` uses `playerOverrides` (the same
|
|
136
|
+
keys, never null, may be empty).
|
|
137
|
+
- `graphics` `fov` accepts 30..120 (was 30..110) in config and patches.
|
|
138
|
+
- `overlayStyle` gains `reticleColor`, `validColor` and `invalidColor` (RGB
|
|
139
|
+
0..1; required in the result, optional in the params patch).
|
|
140
|
+
- `interaction.reticle {state, action}` (required): what the reticle shows
|
|
141
|
+
(`hidden|neutral|typing|target|valid|out_of_range|invalid|holding`) and the
|
|
142
|
+
action it would take (`""|click|grab|pocket|place|mount|select|path|drop`).
|
|
143
|
+
- Everything else is inherited from 0.18 unchanged, including the offload cap
|
|
144
|
+
and device keys; `session.hello` reports `0.19`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hyprune contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,141 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Hyprune schemas · v0
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Hyprune** is an explorable, world-driven desktop environment for Hyprland: your workspaces become places you can walk through, with live windows on the walls. This repository holds the versioned **schemas** for world packages, IPC and manifests, and their validator. Install Hyprune through the [hyprune](https://github.com/hyprune/hyprune) repository (starter kits, Nix, Arch); learn more at [hyprune.com](https://hyprune.com). Licence: MIT.
|
|
4
|
+
|
|
5
|
+
Versioned contracts for Hyprune, a world-driven Hyprland desktop: world packages (formats 0.1–0.7), the IPC protocol (0.1–0.19), extension and screen-type manifests and the input keymap. JSON Schema dialect: **2020-12**. Every version is frozen once published; core, the shell and the SDK pin these exact files. Readable reference: [hyprune.com/reference/schema](https://hyprune.com/reference/schema/).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm i -D @hyprune/schema
|
|
11
|
+
npx hyprune-validate world world.json - 0.7 # a world package manifest
|
|
12
|
+
npx hyprune-validate scene scene.gltf - 0.7 world.json # its glTF against the world format
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import { validate, worldFormats } from '@hyprune/schema';
|
|
17
|
+
import schema from '@hyprune/schema/v0.7/world.schema.json' with { type: 'json' };
|
|
18
|
+
|
|
19
|
+
const result = validate('world', manifest, undefined, worldFormats.at(-1));
|
|
20
|
+
if (!result.valid) console.error(result.errors.join('\n'));
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Every schema file is importable at `@hyprune/schema/v0.N/<name>.schema.json` (`v0/` holds the 0.1 contracts). For a full world authoring workflow (validate, pack, scaffold) use [`@hyprune/sdk`](https://github.com/hyprune/sdk).
|
|
24
|
+
|
|
25
|
+
| Schema | Contract |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `v0/world.schema.json` | Data-only manifest, glTF entry, spawns, anchors, zones, navigation, collision, audio, lightmaps and provenance. |
|
|
28
|
+
| `v0/ipc.schema.json` | JSON-RPC request/response/error envelope, all 12 core methods with typed params/results, 3 notifications and state. |
|
|
29
|
+
| `v0/extension.schema.json` | Process entrypoint, contributions, requested grants and mandatory sandbox profile. |
|
|
30
|
+
| `v0/screen-type.schema.json` | Source kind, planar geometry, resolution, color/alpha, refresh ceiling and input support. |
|
|
31
|
+
| `v0/common.schema.json` | Shared IDs, versions, paths, poses, revisions and capabilities. |
|
|
32
|
+
|
|
33
|
+
[RFC source](https://github.com/hyprune/docs/tree/main/src/content/docs/rfcs) is normative for semantics. [RFC-0003](https://hyprune.com/rfcs/0003-ipc/) defines IPC; [RFC-0004](https://hyprune.com/rfcs/0004-world-format/) defines worlds. The `$id` URLs are mirrored by docs for authoring; this validator registers all schemas locally and never fetches them.
|
|
34
|
+
|
|
35
|
+
## Validate
|
|
36
|
+
|
|
37
|
+
Use Node >=22.12 (CI pins 24.14.0), npm, and the committed lockfile:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
npm ci
|
|
41
|
+
npm test
|
|
42
|
+
npm run validate -- world examples/world.json
|
|
43
|
+
npm run validate -- extension examples/extension.json
|
|
44
|
+
npm run validate -- screen-type examples/screen-type.json
|
|
45
|
+
npm run validate -- ipc examples/ipc/state.delta.notification.json
|
|
46
|
+
npm run validate -- ipc examples/ipc/session.ping.response.json session.ping
|
|
47
|
+
cat examples/world.json | npm run validate -- world -
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Exit 0 = valid, 1 = contract violation, 2 = usage/read/parse failure. The CLI accepts one JSON document up to 1 MiB. Optional method context validates a response against the outstanding request's method, since JSON-RPC responses do not repeat method names. Error responses should be validated as envelopes without a success-method context. Clients must also correlate the response ID themselves.
|
|
51
|
+
|
|
52
|
+
**Why Node:** the docs toolchain already needs it, Ajv supports draft 2020-12 with strict compilation, and JavaScript matches the reference shell/SDK direction. The CLI adds no global install and uses pinned Ajv and SPDX parser dependencies. Python would add a second tool environment here.
|
|
53
|
+
|
|
54
|
+
## Scope and limits
|
|
55
|
+
|
|
56
|
+
Schemas reject unknown fields outside explicit extension maps. The validator adds manifest-local semantic checks: duplicate IDs/material bindings, default spawn references, normalized quaternions, AABB ordering, SPDX expressions, required extension presence, contribution namespaces, advancing deltas and overlay/lease invariants.
|
|
57
|
+
|
|
58
|
+
This is not a runtime transport parser or package installer. It does not check duplicate JSON keys (JSON.parse retains the last), transport framing/depth/session ordering, live grants, asset existence/rights, attribution coverage, glTF indices/UV1, symlinks, archives, codecs, collision or spawn clearance. RFC-0002/0003/0004 require those checks in core and the future SDK. Do not use a passing manifest as proof a package is safe to execute or load.
|
|
59
|
+
|
|
60
|
+
`examples/world.json` is an original synthetic manifest exercising metadata; referenced scene/audio files are intentionally not supplied. It is not a playable package. IPC fixtures cover every request, success result, notification and an error; they are independent shape examples, not a chronological authenticated session. Tokens are omitted, so hello demonstrates negotiation shape, not privileged authentication.
|
|
61
|
+
|
|
62
|
+
## Evolving contracts
|
|
63
|
+
|
|
64
|
+
Update RFC + schema + positive/negative tests + [CHANGELOG.md](CHANGELOG.md) together. Consumers pin a schema commit/release. New structural or semantic contracts get a new protocol/format identifier; never quietly redefine a released one. docs mirrors these exact files with a recorded source commit and checksums. M0/WIP commits are deliberately available before implementation.
|
|
65
|
+
|
|
66
|
+
MIT; see [LICENSE](LICENSE).
|
|
67
|
+
|
|
68
|
+
M1 contracts are frozen separately under `v0.2/`. Select them explicitly:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
validate('ipc', frame, responseMethod, '0.2');
|
|
72
|
+
validate('world', manifest, undefined, '0.2');
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
CLI: `npm run validate -- world world.json - 0.2`. Existing default calls continue validating 0.1. Wire protocol and package format versions are independent.
|
|
76
|
+
|
|
77
|
+
First-session IPC `0.3` lives in `v0.3/{common,ipc}.schema.json` and is selected with
|
|
78
|
+
`validate('ipc', frame, method, '0.3')`. It adds verified shell-child binding,
|
|
79
|
+
workspace locations and bounded map/projection/output descriptors. World format
|
|
80
|
+
selection remains 0.1/0.2; optional Map metadata is documented in RFC-0004/0008.
|
|
81
|
+
|
|
82
|
+
## M3A contract
|
|
83
|
+
|
|
84
|
+
`v0.5/ipc.schema.json` adds hands-on interaction and workspace app state, plus
|
|
85
|
+
custom pose placements. Select version `0.5` explicitly; earlier contracts and
|
|
86
|
+
world format 0.3 remain frozen. App icons are theme names, not arbitrary URLs.
|
|
87
|
+
|
|
88
|
+
IPC **0.12** adds recording/replay control and `record.toggle`; 0.11 remains the
|
|
89
|
+
climbing contract. Both inherit the 0.10 Performance API. Record/replay mutations
|
|
90
|
+
require `input.control`; ordinary observers cannot start capture or replay.
|
|
91
|
+
|
|
92
|
+
IPC **0.13** adds dev-only `camera.author` grants (`camera.photo`/`camera.release`),
|
|
93
|
+
actual camera roll/FOV/lens shift, and Performance controls for ink and visibility.
|
|
94
|
+
World **0.5** adds optional `atmosphere.outline` and directed visibility regions.
|
|
95
|
+
Older schemas remain frozen. Photo grants are not part of a normal shell grant.
|
|
96
|
+
|
|
97
|
+
IPC **0.14** adds nullable `graphics.outline_quality` (`fast` or `smooth`).
|
|
98
|
+
Fast keeps a one-logical-pixel stroke; smooth honours the world's 1–4 px width.
|
|
99
|
+
Low/Medium inherit fast, High/Ultra smooth. This is a graphics-only revision;
|
|
100
|
+
world format remains 0.5 and previous IPC schemas remain frozen.
|
|
101
|
+
|
|
102
|
+
0.14 also adds nullable `outline_width_px` (1–4) and `outline_colour` (three
|
|
103
|
+
0–1 display RGB values). These are persistent user graphics overrides; null means
|
|
104
|
+
use the current world's authored style. The revision-response envelope uses
|
|
105
|
+
`anyOf` so shared `{revision:...}` responses are unambiguous; per-method validation
|
|
106
|
+
still supplies the result type.
|
|
107
|
+
|
|
108
|
+
World format **0.6** adds optional `playable` eye-position volumes (boxes or convex
|
|
109
|
+
hulls), per-area regions and maximum fly height, plus explicit `backdrop.farCards`
|
|
110
|
+
node declarations. IPC remains 0.15; authoring geometry is not added to IPC area
|
|
111
|
+
records. See RFC-0004 for composition, limits and motion semantics.
|
|
112
|
+
|
|
113
|
+
World format **0.7** keeps the 0.6 world.json shape and allows compressed and
|
|
114
|
+
optimised scene assets: `KHR_texture_basisu` (KTX2, material textures only),
|
|
115
|
+
`EXT_meshopt_compression` and `KHR_mesh_quantization`. Lightmaps stay PNG.
|
|
116
|
+
`validate('scene', gltf, undefined, worldFormat, {world})` (CLI:
|
|
117
|
+
`npm run validate -- scene scene.gltf - 0.7 world.json`) checks
|
|
118
|
+
`extensionsRequired` and lightmap textures against the world format. Version
|
|
119
|
+
gates use `atLeast()`; see RFC-0004 "world 0.7".
|
|
120
|
+
|
|
121
|
+
IPC **0.16** adds the `upscaler` graphics key (`"fsr1"`, `"bilinear"` or `null` to
|
|
122
|
+
inherit the preset) to `graphicsConfig`/`graphicsPatch`. Every 0.15 definition is
|
|
123
|
+
otherwise unchanged; earlier schemas stay frozen. See RFC-0003/0008 amendments.
|
|
124
|
+
|
|
125
|
+
IPC **0.17** adds debug capture notes: the `capture.taken` notification (capture ID,
|
|
126
|
+
time and input mode, sent to shells) and `capture.annotate {captureId, note}`
|
|
127
|
+
(shell.control; 0-1000 code points, no control characters). Every 0.16 definition
|
|
128
|
+
is unchanged. See the RFC-0008 amendment "IPC 0.17 capture notes".
|
|
129
|
+
|
|
130
|
+
IPC **0.18** scales the offload power cap to the device: `offload_power_cap_w`
|
|
131
|
+
accepts 20-1000 W or `null` (automatic, the new default), and the new
|
|
132
|
+
`offload_device` key is `"auto"` or a lowercase PCI address. `performance` reports
|
|
133
|
+
where its cap comes from (`capSource`) and the chosen GPU (`device`, or `null`).
|
|
134
|
+
Every 0.17 definition is otherwise unchanged. See the RFC-0009 amendment
|
|
135
|
+
"IPC 0.18 device-scaled offload power and device selection".
|
|
136
|
+
|
|
137
|
+
IPC **0.19** adds player settings (`player.get`/`player.set`: walk/run speed, view
|
|
138
|
+
bob, reticle style/size/colour and reach limits), widens graphics `fov` to 30-120,
|
|
139
|
+
adds `reticleColor`/`validColor`/`invalidColor` to the overlay style and the
|
|
140
|
+
required `interaction.reticle {state, action}`. Every other 0.18 definition is
|
|
141
|
+
unchanged. See the RFC-0006 amendment "IPC 0.19 player settings and reticle".
|
package/bin/validate.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { validate } from '../lib/validate.mjs';
|
|
4
|
+
const [kind, file, method, version, worldFile, ...extra] = process.argv.slice(2);
|
|
5
|
+
if (!kind || !file || extra.length || (worldFile && kind !== 'scene')) {
|
|
6
|
+
console.error('Usage: hyprune-validate <world|extension|screen-type|ipc> <file.json|-> [response-method|-] [contract-version]\n' +
|
|
7
|
+
' hyprune-validate scene <scene.gltf> - <world-format> <world.json>\n(in this repository: npm run validate -- ...)');
|
|
8
|
+
process.exitCode = 2;
|
|
9
|
+
} else {
|
|
10
|
+
try {
|
|
11
|
+
const bytes = readFileSync(file === '-' ? 0 : file);
|
|
12
|
+
if (bytes.length > 1_048_576) throw new Error('Document exceeds 1 MiB');
|
|
13
|
+
const value = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
|
|
14
|
+
const world = worldFile ? JSON.parse(readFileSync(worldFile, 'utf8')) : undefined;
|
|
15
|
+
const result = validate(kind, value, method === '-' ? undefined : method, version, { world });
|
|
16
|
+
if (result.valid) console.log(`VALID ${kind}: ${file}`);
|
|
17
|
+
else { console.error(result.errors.join('\n')); process.exitCode = 1; }
|
|
18
|
+
} catch (error) { console.error(error.message); process.exitCode = 2; }
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifestVersion": "0.1",
|
|
3
|
+
"id": "com.hyprune.clock",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"name": "World clock",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"apiVersion": "0.1",
|
|
8
|
+
"runtime": "process",
|
|
9
|
+
"entrypoint": "bin/clock",
|
|
10
|
+
"capabilities": [
|
|
11
|
+
"state.read"
|
|
12
|
+
],
|
|
13
|
+
"contributes": {
|
|
14
|
+
"widgets": [
|
|
15
|
+
"com.hyprune.clock.widget"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"sandbox": {
|
|
19
|
+
"required": true,
|
|
20
|
+
"network": false
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jsonrpc": "2.0",
|
|
3
|
+
"id": "1",
|
|
4
|
+
"result": {
|
|
5
|
+
"protocol": "0.1",
|
|
6
|
+
"sessionId": "session-1",
|
|
7
|
+
"capabilities": [
|
|
8
|
+
"state.read"
|
|
9
|
+
],
|
|
10
|
+
"methods": [
|
|
11
|
+
"session.hello",
|
|
12
|
+
"session.ping",
|
|
13
|
+
"state.subscribe",
|
|
14
|
+
"state.snapshot",
|
|
15
|
+
"state.unsubscribe"
|
|
16
|
+
],
|
|
17
|
+
"events": [
|
|
18
|
+
"state.delta",
|
|
19
|
+
"runtime.notice",
|
|
20
|
+
"session.revoked"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jsonrpc": "2.0",
|
|
3
|
+
"method": "state.delta",
|
|
4
|
+
"params": {
|
|
5
|
+
"subscriptionId": "sub-1",
|
|
6
|
+
"sessionId": "session-1",
|
|
7
|
+
"baseRevision": 0,
|
|
8
|
+
"revision": 1,
|
|
9
|
+
"changes": {
|
|
10
|
+
"runtime": {
|
|
11
|
+
"active": true,
|
|
12
|
+
"outputs": [
|
|
13
|
+
"output-1"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jsonrpc": "2.0",
|
|
3
|
+
"id": "4",
|
|
4
|
+
"result": {
|
|
5
|
+
"snapshot": {
|
|
6
|
+
"sessionId": "session-1",
|
|
7
|
+
"revision": 0,
|
|
8
|
+
"state": {
|
|
9
|
+
"runtime": {
|
|
10
|
+
"active": false,
|
|
11
|
+
"outputs": [
|
|
12
|
+
"output-1"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"world": null,
|
|
16
|
+
"surfaces": [],
|
|
17
|
+
"movement": {
|
|
18
|
+
"modeId": "com.hyprune.fly",
|
|
19
|
+
"position": [
|
|
20
|
+
0,
|
|
21
|
+
1,
|
|
22
|
+
0
|
|
23
|
+
],
|
|
24
|
+
"orientation": [
|
|
25
|
+
0,
|
|
26
|
+
0,
|
|
27
|
+
0,
|
|
28
|
+
1
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"shell": {
|
|
32
|
+
"leases": []
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|