gbc-scene-forge 0.1.0__tar.gz
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.
- gbc_scene_forge-0.1.0/LICENSE +21 -0
- gbc_scene_forge-0.1.0/Makefile +33 -0
- gbc_scene_forge-0.1.0/PKG-INFO +155 -0
- gbc_scene_forge-0.1.0/README.md +137 -0
- gbc_scene_forge-0.1.0/docs/RELEASING.md +56 -0
- gbc_scene_forge-0.1.0/poetry.lock +1074 -0
- gbc_scene_forge-0.1.0/pyproject.toml +49 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/__init__.py +3 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/apply.py +392 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/contract.py +85 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/documents.py +210 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/paths.py +15 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/progress.py +49 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/server.py +218 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/static/app.js +686 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/static/index.html +109 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/static/model.mjs +83 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/static/progress.mjs +22 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/static/style.css +49 -0
- gbc_scene_forge-0.1.0/src/gbc_scene_forge/transactions.py +176 -0
- gbc_scene_forge-0.1.0/tests/browser.mjs +106 -0
- gbc_scene_forge-0.1.0/tests/fixture_connector.py +223 -0
- gbc_scene_forge-0.1.0/tests/model.mjs +43 -0
- gbc_scene_forge-0.1.0/tests/serve_fixture.py +14 -0
- gbc_scene_forge-0.1.0/tests/test_contract.py +199 -0
- gbc_scene_forge-0.1.0/tests/test_progress.py +149 -0
- gbc_scene_forge-0.1.0/tools/bootstrap_poetry.py +15 -0
- gbc_scene_forge-0.1.0/tools/check_dist.py +43 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael Clifford
|
|
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.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
PYTHON ?= python3
|
|
2
|
+
POETRY ?= .tools/poetry/bin/poetry
|
|
3
|
+
NODE ?= node
|
|
4
|
+
.DEFAULT_GOAL := test
|
|
5
|
+
|
|
6
|
+
.PHONY: setup deps test lint build check-dist clean
|
|
7
|
+
setup:
|
|
8
|
+
$(PYTHON) tools/bootstrap_poetry.py
|
|
9
|
+
$(MAKE) deps
|
|
10
|
+
|
|
11
|
+
deps:
|
|
12
|
+
test -x .venv/bin/python || .tools/poetry/bin/python -m venv .venv
|
|
13
|
+
$(POETRY) config virtualenvs.in-project true --local
|
|
14
|
+
$(POETRY) check --lock --strict
|
|
15
|
+
$(POETRY) sync
|
|
16
|
+
|
|
17
|
+
test:
|
|
18
|
+
$(POETRY) run python -m unittest discover -s tests -p 'test_*.py'
|
|
19
|
+
$(NODE) tests/model.mjs
|
|
20
|
+
|
|
21
|
+
lint:
|
|
22
|
+
$(POETRY) run ruff check .
|
|
23
|
+
$(POETRY) run ruff format --check .
|
|
24
|
+
|
|
25
|
+
build:
|
|
26
|
+
$(POETRY) run python -m build
|
|
27
|
+
$(POETRY) run twine check --strict dist/*
|
|
28
|
+
$(POETRY) run python tools/check_dist.py
|
|
29
|
+
|
|
30
|
+
check-dist: build
|
|
31
|
+
|
|
32
|
+
clean:
|
|
33
|
+
rm -rf build dist
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gbc-scene-forge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local browser scene editor with game-owned connectors
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: game-boy-color,scene-editor,tilemap
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Topic :: Games/Entertainment
|
|
13
|
+
Project-URL: Documentation, https://github.com/cliffom/gbc-scene-forge/blob/main/README.md
|
|
14
|
+
Project-URL: Issues, https://github.com/cliffom/gbc-scene-forge/issues
|
|
15
|
+
Project-URL: Repository, https://github.com/cliffom/gbc-scene-forge
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# GBC Scene Forge
|
|
19
|
+
|
|
20
|
+
Version 0.1.0 is a local browser editor with an explicitly supplied Python game
|
|
21
|
+
connector. It has no runtime Python dependencies. The package contains its HTTP
|
|
22
|
+
service, browser UI, document storage, task runner and durable transaction store.
|
|
23
|
+
Atlas decoding, rendering, source translation and game builds belong to the host
|
|
24
|
+
connector. No connector is discovered or executed automatically.
|
|
25
|
+
|
|
26
|
+
## Development
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
make setup PYTHON=python3.12
|
|
30
|
+
make lint test build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The build creates `dist/gbc_scene_forge-0.1.0-py3-none-any.whl` and a source
|
|
34
|
+
archive, and tests the wheel in a clean environment. See
|
|
35
|
+
[building and releasing](docs/RELEASING.md) for tooling and manual PyPI publication.
|
|
36
|
+
There is no published release yet. Local hosts can install this checkout with
|
|
37
|
+
`python -m pip install -e ../gbc-scene-forge` or use their dependency manager's
|
|
38
|
+
editable path support.
|
|
39
|
+
|
|
40
|
+
## Launching
|
|
41
|
+
|
|
42
|
+
Install the package through the host project's locked dependencies. A host launcher
|
|
43
|
+
constructs its connector and calls:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from gbc_scene_forge.server import serve
|
|
47
|
+
|
|
48
|
+
serve(connector, port=8765)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The connector supplies an explicit `Workspace(root, drafts, history, reviews)`.
|
|
52
|
+
The service binds to loopback and uses a per-session mutation token. Connectors
|
|
53
|
+
are trusted local Python code, not a sandboxed plugin system. The host must recover
|
|
54
|
+
existing transactions before importing game modules that require approved sources.
|
|
55
|
+
|
|
56
|
+
## Connector contract version 1
|
|
57
|
+
|
|
58
|
+
`gbc_scene_forge.contract.Connector` specifies the interface. Its implementation
|
|
59
|
+
supplies:
|
|
60
|
+
|
|
61
|
+
| Method | Responsibility |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `catalog()` | Project identity, capabilities, target profiles, image families and asset entries |
|
|
64
|
+
| `load(target, template=False)` | Working scene, fixed cells, constraints, marker annotations and draft revision |
|
|
65
|
+
| `normalize(scene)` / `check_shape(scene)` | Legacy document interpretation and structural game validity |
|
|
66
|
+
| `source_revision(target)` | Opaque revision of relevant source dependencies |
|
|
67
|
+
| `preview(scene, light, state, frame)` | PNG data URL, collision grid and authoritative comparison result |
|
|
68
|
+
| `validate(scene)` | Validity, errors/warnings and structured issues |
|
|
69
|
+
| `compare(scene)` | Whether game-relevant content differs; not restricted to the cell grid |
|
|
70
|
+
| `asset(name)` / `export(scene)` | Encoded image bytes and the connector's portable handoff |
|
|
71
|
+
| `input_files(root)` / `output_files(root)` | Explicit workspace file inventories |
|
|
72
|
+
| `prepare(scene, stage, review_id)` | Staged candidate and a `BuildPlan` |
|
|
73
|
+
| `approve(plan, stage, review_id)` | Bind project-specific approval metadata after explicit review confirmation |
|
|
74
|
+
| `activity(text, fallback)` / `refresh()` | Project-specific activity descriptions and cache invalidation |
|
|
75
|
+
|
|
76
|
+
Catalog profiles declare `cell_size`, `erase_cell`, `lighting`, `states`, optional
|
|
77
|
+
`guide` dimensions and `animation_frames`/`animation_interval_ms`/`animation_label`. Asset entries declare
|
|
78
|
+
opaque `id`, display label, family, compatible profiles, and either an explicit
|
|
79
|
+
image `rect` or a stamp's `cells`. Sprite references set `reference: true`; their
|
|
80
|
+
rectangles may declare an origin. The browser never decodes IDs or map characters.
|
|
81
|
+
|
|
82
|
+
Capabilities control Apply, export, templates and composition references. Every
|
|
83
|
+
project supplies at least one profile and preview mode. Required contract methods
|
|
84
|
+
remain available even when an operation reports unsupported capabilities.
|
|
85
|
+
|
|
86
|
+
The working grid schema retains `profile` as the opaque target key and
|
|
87
|
+
`source_digest` as an opaque revision for compatibility. Fixed coordinates are
|
|
88
|
+
returned as `locked`; `constraints` supplies reasons. Conditional game rules stay
|
|
89
|
+
authoritative in connector validation. Issue objects contain `code`, `message`
|
|
90
|
+
and, when available, a cell or region location.
|
|
91
|
+
|
|
92
|
+
## Documents
|
|
93
|
+
|
|
94
|
+
New saves and JSON downloads use envelope version 2:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"version": 2,
|
|
99
|
+
"connector": "example-game",
|
|
100
|
+
"id": "draft-name",
|
|
101
|
+
"name": "Draft name",
|
|
102
|
+
"target": "room",
|
|
103
|
+
"source_revision": "opaque-revision",
|
|
104
|
+
"content": {
|
|
105
|
+
"width": 7,
|
|
106
|
+
"height": 5,
|
|
107
|
+
"cells": [],
|
|
108
|
+
"references": []
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The illustrative `cells` must contain the declared number of rows and columns in
|
|
114
|
+
a real document. Connector extensions live inside `content` and survive saves.
|
|
115
|
+
Version-1 flat documents pass through connector normalization. Loading leaves
|
|
116
|
+
their original bytes untouched; saving migrates that file with its existing ID
|
|
117
|
+
and raw-byte revision guard. Unsupported versions, connector identities and
|
|
118
|
+
unrecognized envelope fields are rejected without rewriting files. Existing
|
|
119
|
+
source-staleness checks still apply to migrated drafts.
|
|
120
|
+
|
|
121
|
+
## Apply and recovery
|
|
122
|
+
|
|
123
|
+
`BuildPlan` declares candidate source paths, allowed outputs, required artifacts,
|
|
124
|
+
ordered `CheckStep` commands, environment, review views and approval data. Commands
|
|
125
|
+
are argument arrays, run in an isolated candidate directory. Preparation and
|
|
126
|
+
approval operate on that directory; connectors must not mutate live sources.
|
|
127
|
+
|
|
128
|
+
The runner checks source, candidate and installed editor-package fingerprints, rejects escaping paths,
|
|
129
|
+
requires declared artifacts, excludes only declared outputs from the frozen-source
|
|
130
|
+
comparison, and promotes only declared sources/outputs. It preserves process-group
|
|
131
|
+
cleanup, bounded output, worker health, reconnectable status, conflict-aware
|
|
132
|
+
rollback and interrupted-transaction recovery. Existing transaction/job formats
|
|
133
|
+
are retained; history paths come from the workspace.
|
|
134
|
+
|
|
135
|
+
## Independent acceptance fixture
|
|
136
|
+
|
|
137
|
+
`tests/fixture_connector.py` provides a different 7 × 5 scene with four-pixel cells,
|
|
138
|
+
opaque asset IDs, non-grid game content, JSON sources and a small Python compiler.
|
|
139
|
+
It imports no host game, atlas library or imaging library. Run:
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
.venv/bin/python -m unittest discover -s tests -p 'test_*.py'
|
|
143
|
+
.venv/bin/python tests/serve_fixture.py --root /tmp/forge-fixture --port 8777
|
|
144
|
+
node tests/browser.mjs http://127.0.0.1:8777/
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The browser check requires a local Chrome installation; its third argument can
|
|
148
|
+
override the default macOS executable. The fixture proves this contract is
|
|
149
|
+
independent of one game. Additional real games may require explicit future
|
|
150
|
+
capabilities rather than game-specific branches in the editor.
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
[MIT](LICENSE). Copyright (c) 2026 Michael Clifford.
|
|
155
|
+
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# GBC Scene Forge
|
|
2
|
+
|
|
3
|
+
Version 0.1.0 is a local browser editor with an explicitly supplied Python game
|
|
4
|
+
connector. It has no runtime Python dependencies. The package contains its HTTP
|
|
5
|
+
service, browser UI, document storage, task runner and durable transaction store.
|
|
6
|
+
Atlas decoding, rendering, source translation and game builds belong to the host
|
|
7
|
+
connector. No connector is discovered or executed automatically.
|
|
8
|
+
|
|
9
|
+
## Development
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
make setup PYTHON=python3.12
|
|
13
|
+
make lint test build
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The build creates `dist/gbc_scene_forge-0.1.0-py3-none-any.whl` and a source
|
|
17
|
+
archive, and tests the wheel in a clean environment. See
|
|
18
|
+
[building and releasing](docs/RELEASING.md) for tooling and manual PyPI publication.
|
|
19
|
+
There is no published release yet. Local hosts can install this checkout with
|
|
20
|
+
`python -m pip install -e ../gbc-scene-forge` or use their dependency manager's
|
|
21
|
+
editable path support.
|
|
22
|
+
|
|
23
|
+
## Launching
|
|
24
|
+
|
|
25
|
+
Install the package through the host project's locked dependencies. A host launcher
|
|
26
|
+
constructs its connector and calls:
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from gbc_scene_forge.server import serve
|
|
30
|
+
|
|
31
|
+
serve(connector, port=8765)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The connector supplies an explicit `Workspace(root, drafts, history, reviews)`.
|
|
35
|
+
The service binds to loopback and uses a per-session mutation token. Connectors
|
|
36
|
+
are trusted local Python code, not a sandboxed plugin system. The host must recover
|
|
37
|
+
existing transactions before importing game modules that require approved sources.
|
|
38
|
+
|
|
39
|
+
## Connector contract version 1
|
|
40
|
+
|
|
41
|
+
`gbc_scene_forge.contract.Connector` specifies the interface. Its implementation
|
|
42
|
+
supplies:
|
|
43
|
+
|
|
44
|
+
| Method | Responsibility |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| `catalog()` | Project identity, capabilities, target profiles, image families and asset entries |
|
|
47
|
+
| `load(target, template=False)` | Working scene, fixed cells, constraints, marker annotations and draft revision |
|
|
48
|
+
| `normalize(scene)` / `check_shape(scene)` | Legacy document interpretation and structural game validity |
|
|
49
|
+
| `source_revision(target)` | Opaque revision of relevant source dependencies |
|
|
50
|
+
| `preview(scene, light, state, frame)` | PNG data URL, collision grid and authoritative comparison result |
|
|
51
|
+
| `validate(scene)` | Validity, errors/warnings and structured issues |
|
|
52
|
+
| `compare(scene)` | Whether game-relevant content differs; not restricted to the cell grid |
|
|
53
|
+
| `asset(name)` / `export(scene)` | Encoded image bytes and the connector's portable handoff |
|
|
54
|
+
| `input_files(root)` / `output_files(root)` | Explicit workspace file inventories |
|
|
55
|
+
| `prepare(scene, stage, review_id)` | Staged candidate and a `BuildPlan` |
|
|
56
|
+
| `approve(plan, stage, review_id)` | Bind project-specific approval metadata after explicit review confirmation |
|
|
57
|
+
| `activity(text, fallback)` / `refresh()` | Project-specific activity descriptions and cache invalidation |
|
|
58
|
+
|
|
59
|
+
Catalog profiles declare `cell_size`, `erase_cell`, `lighting`, `states`, optional
|
|
60
|
+
`guide` dimensions and `animation_frames`/`animation_interval_ms`/`animation_label`. Asset entries declare
|
|
61
|
+
opaque `id`, display label, family, compatible profiles, and either an explicit
|
|
62
|
+
image `rect` or a stamp's `cells`. Sprite references set `reference: true`; their
|
|
63
|
+
rectangles may declare an origin. The browser never decodes IDs or map characters.
|
|
64
|
+
|
|
65
|
+
Capabilities control Apply, export, templates and composition references. Every
|
|
66
|
+
project supplies at least one profile and preview mode. Required contract methods
|
|
67
|
+
remain available even when an operation reports unsupported capabilities.
|
|
68
|
+
|
|
69
|
+
The working grid schema retains `profile` as the opaque target key and
|
|
70
|
+
`source_digest` as an opaque revision for compatibility. Fixed coordinates are
|
|
71
|
+
returned as `locked`; `constraints` supplies reasons. Conditional game rules stay
|
|
72
|
+
authoritative in connector validation. Issue objects contain `code`, `message`
|
|
73
|
+
and, when available, a cell or region location.
|
|
74
|
+
|
|
75
|
+
## Documents
|
|
76
|
+
|
|
77
|
+
New saves and JSON downloads use envelope version 2:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"version": 2,
|
|
82
|
+
"connector": "example-game",
|
|
83
|
+
"id": "draft-name",
|
|
84
|
+
"name": "Draft name",
|
|
85
|
+
"target": "room",
|
|
86
|
+
"source_revision": "opaque-revision",
|
|
87
|
+
"content": {
|
|
88
|
+
"width": 7,
|
|
89
|
+
"height": 5,
|
|
90
|
+
"cells": [],
|
|
91
|
+
"references": []
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The illustrative `cells` must contain the declared number of rows and columns in
|
|
97
|
+
a real document. Connector extensions live inside `content` and survive saves.
|
|
98
|
+
Version-1 flat documents pass through connector normalization. Loading leaves
|
|
99
|
+
their original bytes untouched; saving migrates that file with its existing ID
|
|
100
|
+
and raw-byte revision guard. Unsupported versions, connector identities and
|
|
101
|
+
unrecognized envelope fields are rejected without rewriting files. Existing
|
|
102
|
+
source-staleness checks still apply to migrated drafts.
|
|
103
|
+
|
|
104
|
+
## Apply and recovery
|
|
105
|
+
|
|
106
|
+
`BuildPlan` declares candidate source paths, allowed outputs, required artifacts,
|
|
107
|
+
ordered `CheckStep` commands, environment, review views and approval data. Commands
|
|
108
|
+
are argument arrays, run in an isolated candidate directory. Preparation and
|
|
109
|
+
approval operate on that directory; connectors must not mutate live sources.
|
|
110
|
+
|
|
111
|
+
The runner checks source, candidate and installed editor-package fingerprints, rejects escaping paths,
|
|
112
|
+
requires declared artifacts, excludes only declared outputs from the frozen-source
|
|
113
|
+
comparison, and promotes only declared sources/outputs. It preserves process-group
|
|
114
|
+
cleanup, bounded output, worker health, reconnectable status, conflict-aware
|
|
115
|
+
rollback and interrupted-transaction recovery. Existing transaction/job formats
|
|
116
|
+
are retained; history paths come from the workspace.
|
|
117
|
+
|
|
118
|
+
## Independent acceptance fixture
|
|
119
|
+
|
|
120
|
+
`tests/fixture_connector.py` provides a different 7 × 5 scene with four-pixel cells,
|
|
121
|
+
opaque asset IDs, non-grid game content, JSON sources and a small Python compiler.
|
|
122
|
+
It imports no host game, atlas library or imaging library. Run:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
.venv/bin/python -m unittest discover -s tests -p 'test_*.py'
|
|
126
|
+
.venv/bin/python tests/serve_fixture.py --root /tmp/forge-fixture --port 8777
|
|
127
|
+
node tests/browser.mjs http://127.0.0.1:8777/
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The browser check requires a local Chrome installation; its third argument can
|
|
131
|
+
override the default macOS executable. The fixture proves this contract is
|
|
132
|
+
independent of one game. Additional real games may require explicit future
|
|
133
|
+
capabilities rather than game-specific branches in the editor.
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
[MIT](LICENSE). Copyright (c) 2026 Michael Clifford.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Building and releasing
|
|
2
|
+
|
|
3
|
+
Python 3.10+ and Make are required. The commands below select Python 3.12;
|
|
4
|
+
set `PYTHON` to another supported interpreter if needed. Node 24 runs the browser-model tests; the
|
|
5
|
+
editor itself needs no Node installation. Development dependencies are locked in
|
|
6
|
+
`poetry.lock`; `make setup` bootstraps Poetry 2.4.2 into `.tools/poetry` and installs
|
|
7
|
+
the development environment into `.venv`.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
make setup PYTHON=python3.12
|
|
11
|
+
make lint test
|
|
12
|
+
make build
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`make build` uses the standard isolated Python build frontend: it creates the
|
|
16
|
+
source distribution, then builds the wheel from that source distribution. It
|
|
17
|
+
checks metadata with Twine, installs the wheel without dependencies into a clean
|
|
18
|
+
environment, verifies bundled browser files and runs the Python contracts against
|
|
19
|
+
that installed wheel. Artifacts appear in `dist/`. Use `make clean` before building
|
|
20
|
+
a different version. No command above uploads packages.
|
|
21
|
+
|
|
22
|
+
CI runs these checks on Python 3.10, 3.12 and 3.14. The independent browser
|
|
23
|
+
acceptance check is optional and requires Chrome; see the README.
|
|
24
|
+
|
|
25
|
+
## Publication
|
|
26
|
+
|
|
27
|
+
The project uses the MIT license, included in both distribution formats. Before a
|
|
28
|
+
first release, confirm the package name is available on the intended index.
|
|
29
|
+
Keep the version in `pyproject.toml` and `src/gbc_scene_forge/__init__.py` in sync;
|
|
30
|
+
the installed-wheel check enforces this.
|
|
31
|
+
|
|
32
|
+
Create GitHub environments `testpypi` and `pypi`. Register a trusted publisher on
|
|
33
|
+
each index with:
|
|
34
|
+
|
|
35
|
+
- Owner: `cliffom`
|
|
36
|
+
- Repository: `gbc-scene-forge`
|
|
37
|
+
- Workflow: `publish.yml`
|
|
38
|
+
- Environment: `testpypi` or `pypi`, matching the index
|
|
39
|
+
- Package name: `gbc-scene-forge`
|
|
40
|
+
|
|
41
|
+
For a new package, register a pending publisher through the index account's
|
|
42
|
+
publishing page. Use the official [trusted publisher setup guide](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/).
|
|
43
|
+
The workflow follows the [Python Packaging User Guide](https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/)
|
|
44
|
+
and uses short-lived OIDC credentials; no PyPI API token is stored in the repository.
|
|
45
|
+
|
|
46
|
+
After reviewing and committing a release, create and push an annotated `v0.1.0`
|
|
47
|
+
tag (or the matching next version). Run **Publish package** manually against that
|
|
48
|
+
tag, selecting `testpypi` first. Check that installation and the host connector
|
|
49
|
+
work before manually running the workflow for `pypi`. The workflow rebuilds and
|
|
50
|
+
checks the distributions, checks the tag against the package version, then uploads
|
|
51
|
+
only those verified artifacts. Pushing a tag alone does not publish.
|
|
52
|
+
|
|
53
|
+
Once a real release is available, consumers can pin `gbc-scene-forge==0.1.0`.
|
|
54
|
+
Until then, Settlement uses a sibling editable path dependency, so clone both
|
|
55
|
+
repositories beside one another. Its CI also checks out the sibling repository;
|
|
56
|
+
it needs this repository's initial commit pushed before it can run successfully.
|