This website requires JavaScript.
Explore
Help
Sign In
meleki
/
feuerwerk
Watch
1
Star
0
Fork
0
Code
Issues
38
Actions
Projects
1
Wiki
Activity
Files
defd4a86d220c02d65e54b2ccf802052c78fed94
feuerwerk
/
tools
/
e2e
T
History
admin
and
Claude Opus 5
defd4a86d2
game-maker / suite (push)
Failing after 1m41s
Details
game-maker / gate (push)
Successful in 2m2s
Details
The live dt in the graph is not always three decimals: the check in module 18 that reads the value an output last carried asked for /^0\.\d{3} dt$/, but formatNumber trims trailing zeros, so a frame of exactly 50 ms reads as "0.05" - that is why the suite for
5ba796a
was red in CI with this single FAIL while the same check is green on this machine, where the frame time never lands on a round number; the check now asks for any number of decimals, which is what it was ever about, and the reason stands as a comment next to it (
#119
)
...
Co-Authored-By: Claude Opus 5 <
noreply@anthropic.com
>
2026-09-20 15:41:43 +02:00
..
lib
Asset panel grouped by kind with icons: assets are listed under a header per kind (Sprites, Behaviors, ...) with the count on the right, empty groups are not shown, every group starts folded when a project is opened, a click on the header folds and unfolds it, selecting an asset elsewhere unfolds its group and folding the group of the selected asset clears the selection; every asset kind has an SVG icon in src/editor/panels/icons/ drawn before the name, the pure rule for grouping and sorting lives in assetGroups.ts; the same icons replace the kind word in document tabs and the overflow menu (a list icon for the List tab, which also fixes the close x lying over the end of the active tab's text), stand before every entry of the + menu (Button got an icon option) and on the right of scene object rows instead of the type name; the colour swatch next to sprite names is gone from both panels; the SVG loader moved to src/ui/svg.ts for both icon sets; test hook assetRow unfolds the group and scrolls to the row, assetRowShown only reads, new hook menuIcons; e2e 4g and 4h, 14 and 44a check the icons (
#176
)
2026-09-19 18:36:20 +02:00
01-hierarchy.mjs
Open asset greyed out and real tab cards: Open asset in the scene object menu is only pickable for kinds with an editor of their own, the table of which asset opens which tab moved from Editor.ts into the new module assetTabs.ts with hasAssetEditor so the menu and the editor read the same list, Select asset stays as it was; tabs are drawn as index cards (new module TabButton.ts): the one showing is a light grey card instead of the aggressive blue, rounded above and square below, its name in plain weight and measured bold so it never clips itself, and a mouse down on the tab already showing keeps its colour; the padding left and right grew to 6 px in one place for both kinds of tab, Scene and Game carry an icon too (the scene one from the asset panel, a new game.svg play sign), Plugins and a plugin's own tab have none; new test hook menuEnabled next to menuRows and menuIcons, e2e 01 checks the greyed out entry on a sprite row, 14a-ii the card and the icons of the fixed tabs, 44a the icon at the wider padding (
#176
)
2026-09-20 11:40:01 +02:00
02-inspector.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
03-play.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
04-assets.mjs
Asset panel grouped by kind with icons: assets are listed under a header per kind (Sprites, Behaviors, ...) with the count on the right, empty groups are not shown, every group starts folded when a project is opened, a click on the header folds and unfolds it, selecting an asset elsewhere unfolds its group and folding the group of the selected asset clears the selection; every asset kind has an SVG icon in src/editor/panels/icons/ drawn before the name, the pure rule for grouping and sorting lives in assetGroups.ts; the same icons replace the kind word in document tabs and the overflow menu (a list icon for the List tab, which also fixes the close x lying over the end of the active tab's text), stand before every entry of the + menu (Button got an icon option) and on the right of scene object rows instead of the type name; the colour swatch next to sprite names is gone from both panels; the SVG loader moved to src/ui/svg.ts for both icon sets; test hook assetRow unfolds the group and scrolls to the row, assetRowShown only reads, new hook menuIcons; e2e 4g and 4h, 14 and 44a check the icons (
#176
)
2026-09-19 18:36:20 +02:00
05-drawing.mjs
Scene view symbols come from SVG files: the behavior, container, rigidbody, camera and particles icons live in src/viewport/icons/ and are changed by editing the file and running npm run build; they are bundled, parsed once and drawn into a Graphics by the new module symbolIcons.ts, currentColor becomes the theme color of the symbol, the origin sits in the middle with a centered viewBox and the same units as before, so the symbols are pixel for pixel unchanged; what depends on the object (camera frame, collider outline, one-way cone) stays in code; unit tests keep the files to what Pixi's SVG parser and a browser draw alike (no transform, no polygon, fill always given), e2e 5c reads the five symbols in the theme color (
#175
)
2026-09-19 17:07:56 +02:00
06-graph.mjs
Tabs are open documents: Scene, Game and Plugins stay as fixed tabs, every other asset opens in its own tab (double click or Enter in the asset panel, on creation, from the list button), several assets of one kind can be open at once, a tab is labelled with its kind dimmed before the name, cut at 160 px and renamed with its asset, closes with its x or a middle click and goes away when its asset is deleted; a tab always shows its own document instead of following the selection, the picker in the tab head is gone, zoom and scroll are kept per document for the session and dropped on close, a double click on a call node stays in the same tab with breadcrumbs per tab; one editor per kind is switched between documents, the placement rules live in the pure module documents.ts, and the test hook showTab stays as a compatibility path; new e2e module 44 documents (
#171
)
2026-09-19 15:49:54 +02:00
07-parenting.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
08-colliders.mjs
Collision layers and masks: a collider carries a layer and a mask of the layers it meets, and the pair only meets when both masks name the other's layer - the rule is one pure module (src/core/model/collisionLayers.ts) with layerBit, layersMeet and the names a project starts with, so the three places that have to agree read the same function: the editor run through CollisionSystem, the Solids sweep per pair and Rapier, where the mask becomes the collider's interaction groups; the project file gained collisionLayers: ["Default"] (default one layer, no formatVersion bump), the collider schema two new kinds - layer as a dropdown of the project's layers and layerMask as a menu of tickboxes that stays open while it is ticked (Menu.ts learned rows that do not close on a pick) - and the names are edited through "Collision layers..." in the toolbar's Project menu, not a Project tab, which is the decision I made myself because the question ran into the MCP timeout: the dialog (src/editor/CollisionLayersDialog.ts) holds up to 16 names, Add layer appends "Layer <n>" and Apply writes all of them as one undo step (SetCollisionLayersCommand); a mask read from a file goes through a check that refuses anything that is not a finite number, because Number(null) is 0 and a collidesWith: null would silently have meant "meets nothing"; 9 new e2e checks in module 8 cover the menu entry, the dialog, Add layer, Apply and its undo, both inspector rows, the tickbox menu, and the mover walking straight through the crate that 8c blocked on once their layers no longer meet, and 21 new unit tests cover the rule, the schema and the command (
#152
)
2026-09-20 15:31:22 +02:00
09-containers.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
10-text-and-enabled.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
11-menus.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
12-textures.mjs
The texture field only offers pictures: each texture with its frames, no animations any more; an animation id left in an older project shows as a missing reference (
#143
)
2026-09-18 12:14:01 +02:00
13-frames.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
14-overflow.mjs
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (
#126
,
#127
), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in
#117
, written down in the wiki for
#115
and
#116
; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (
#119
)
2026-09-20 14:24:27 +02:00
15-aspect.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
16-container.mjs
Tabs are open documents: Scene, Game and Plugins stay as fixed tabs, every other asset opens in its own tab (double click or Enter in the asset panel, on creation, from the list button), several assets of one kind can be open at once, a tab is labelled with its kind dimmed before the name, cut at 160 px and renamed with its asset, closes with its x or a middle click and goes away when its asset is deleted; a tab always shows its own document instead of following the selection, the picker in the tab head is gone, zoom and scroll are kept per document for the session and dropped on close, a double click on a call node stays in the same tab with breadcrumbs per tab; one editor per kind is switched between documents, the placement rules live in the pure module documents.ts, and the test hook showTab stays as a compatibility path; new e2e module 44 documents (
#171
)
2026-09-19 15:49:54 +02:00
17-editor-run.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
18-pause.mjs
The live dt in the graph is not always three decimals: the check in module 18 that reads the value an output last carried asked for /^0\.\d{3} dt$/, but formatNumber trims trailing zeros, so a frame of exactly 50 ms reads as "0.05" - that is why the suite for
5ba796a
was red in CI with this single FAIL while the same check is green on this machine, where the frame time never lands on a round number; the check now asks for any number of decimals, which is what it was ever about, and the reason stands as a comment next to it (
#119
)
2026-09-20 15:41:43 +02:00
19-nested-behavior.mjs
Tabs are open documents: Scene, Game and Plugins stay as fixed tabs, every other asset opens in its own tab (double click or Enter in the asset panel, on creation, from the list button), several assets of one kind can be open at once, a tab is labelled with its kind dimmed before the name, cut at 160 px and renamed with its asset, closes with its x or a middle click and goes away when its asset is deleted; a tab always shows its own document instead of following the selection, the picker in the tab head is gone, zoom and scroll are kept per document for the session and dropped on close, a double click on a call node stays in the same tab with breadcrumbs per tab; one editor per kind is switched between documents, the placement rules live in the pure module documents.ts, and the test hook showTab stays as a compatibility path; new e2e module 44 documents (
#171
)
2026-09-19 15:49:54 +02:00
20-key-repeat.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
21-list.mjs
Tabs are open documents: Scene, Game and Plugins stay as fixed tabs, every other asset opens in its own tab (double click or Enter in the asset panel, on creation, from the list button), several assets of one kind can be open at once, a tab is labelled with its kind dimmed before the name, cut at 160 px and renamed with its asset, closes with its x or a middle click and goes away when its asset is deleted; a tab always shows its own document instead of following the selection, the picker in the tab head is gone, zoom and scroll are kept per document for the session and dropped on close, a double click on a call node stays in the same tab with breadcrumbs per tab; one editor per kind is switched between documents, the placement rules live in the pure module documents.ts, and the test hook showTab stays as a compatibility path; new e2e module 44 documents (
#171
)
2026-09-19 15:49:54 +02:00
22-struct.mjs
Number fields drop trailing zeros: formatNumber still rounds to at most 3 decimals and then removes zeros at the end, so 100.000 reads 100 and 0.500 reads 0.5, everywhere (inspector, graph and shader nodes, duration and fps in the animation and tile tabs); a field's own decimals is now an upper limit, stored values are unchanged, -0 still shows as 0, and the graph's separate integer rule is gone (
#172
)
2026-09-19 14:29:00 +02:00
23-variable-nodes.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
24-property-nodes.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
25-animation.mjs
Timeline keys can be copied and pasted at the playhead, duplicated with Ctrl+drag, and frames inserted or removed from a right-click menu (
#102
)
2026-09-17 12:53:56 +02:00
26-state-machine.mjs
Several transitions between the same pair of states: make transition onto a state that is already connected in that direction adds another transition, which gets its own name right away (Transition 2, Transition 3, skipping names that already leave the state), so two unnamed transitions between one pair never exist; renaming is refused when another transition between the same pair in the same direction already carries the name, the empty name included, while equal names to other targets are only warned about as before; the behavior graph keeps Already connected; self transitions may repeat too, each further loop drawn as a ring around the previous one with the preview showing the next ring, and transition labels that would cover another one slide along their own edge until they are free (pure function freeLabelSpot); test hook transitionLabelAt also returns width and height, e2e 26e6 (
#162
)
2026-09-19 16:30:52 +02:00
27-console.mjs
Shaders draw in the sprite's own pass: a Mesh with the graph's fragment, no filter (
#77
)
2026-09-13 15:31:08 +02:00
28-shader.mjs
Number fields drop trailing zeros: formatNumber still rounds to at most 3 decimals and then removes zeros at the end, so 100.000 reads 100 and 0.500 reads 0.5, everywhere (inspector, graph and shader nodes, duration and fps in the animation and tile tabs); a field's own decimals is now an upper limit, stored values are unchanged, -0 still shows as 0, and the graph's separate integer rule is gone (
#172
)
2026-09-19 14:29:00 +02:00
29-transform.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
30-font.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
31-particles.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
32-scope.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
33-render-on-change.mjs
Asset panel grouped by kind with icons: assets are listed under a header per kind (Sprites, Behaviors, ...) with the count on the right, empty groups are not shown, every group starts folded when a project is opened, a click on the header folds and unfolds it, selecting an asset elsewhere unfolds its group and folding the group of the selected asset clears the selection; every asset kind has an SVG icon in src/editor/panels/icons/ drawn before the name, the pure rule for grouping and sorting lives in assetGroups.ts; the same icons replace the kind word in document tabs and the overflow menu (a list icon for the List tab, which also fixes the close x lying over the end of the active tab's text), stand before every entry of the + menu (Button got an icon option) and on the right of scene object rows instead of the type name; the colour swatch next to sprite names is gone from both panels; the SVG loader moved to src/ui/svg.ts for both icon sets; test hook assetRow unfolds the group and scrolls to the row, assetRowShown only reads, new hook menuIcons; e2e 4g and 4h, 14 and 44a check the icons (
#176
)
2026-09-19 18:36:20 +02:00
34-sound.mjs
A test that waits for a deadline somebody guessed is waiting for the wrong thing, so it waits for the editor (
#93
)
2026-09-16 08:08:10 +02:00
35-load-scene.mjs
Asset panel grouped by kind with icons: assets are listed under a header per kind (Sprites, Behaviors, ...) with the count on the right, empty groups are not shown, every group starts folded when a project is opened, a click on the header folds and unfolds it, selecting an asset elsewhere unfolds its group and folding the group of the selected asset clears the selection; every asset kind has an SVG icon in src/editor/panels/icons/ drawn before the name, the pure rule for grouping and sorting lives in assetGroups.ts; the same icons replace the kind word in document tabs and the overflow menu (a list icon for the List tab, which also fixes the close x lying over the end of the active tab's text), stand before every entry of the + menu (Button got an icon option) and on the right of scene object rows instead of the type name; the colour swatch next to sprite names is gone from both panels; the SVG loader moved to src/ui/svg.ts for both icon sets; test hook assetRow unfolds the group and scrolls to the row, assetRowShown only reads, new hook menuIcons; e2e 4g and 4h, 14 and 44a check the icons (
#176
)
2026-09-19 18:36:20 +02:00
36-graph-groups.mjs
A box drawn around a part of the graph is part of it, so a fit frames it and a band catches it (
#95
)
2026-09-16 14:23:56 +02:00
37-nine-slice.mjs
A frame with borders tiles unless told to stretch
2026-09-16 18:13:11 +02:00
38-plugins.mjs
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (
#126
,
#127
), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in
#117
, written down in the wiki for
#115
and
#116
; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (
#119
)
2026-09-20 14:24:27 +02:00
39-tile.mjs
The autotile asset is renamed to tile and gains a plain None (1 × 1) kind, which is now the default; older projects load their autotiles as floor tiles (
#131
)
2026-09-18 08:01:07 +02:00
40-tilemap.mjs
Each tilemap layer has its own Z: an offset added to the Z of the placed tilemap, like a child's Z to its parent, default 0 keeps the previous order (layers right after their map, in list order), a negative Z sorts a layer below the map, on a tie layers keep their list order and follow the hierarchy against other objects; editor scene and game use the same order through the new pure function drawSlots, a tilemap draws into one container per layer, and the tilemap panel gains a Z field for the selected layer with one undo step per change (
#174
)
2026-09-19 14:03:20 +02:00
41-physics.mjs
One-way platforms, raycast and collision stay with contact data: a collider can be one-way with a side it blocks from (turning with its object, drawn thick in the scene view) and a tile can be one-way from above, one-way cells never merge with solid tiles, a contact blocks only when its normal is within 45 degrees of the blocking side, the new node Ignore one-way lets an object drop through for a while, and it all holds for Move and for dynamic bodies in Rapier, where the decision is made before each step because the hook may not touch the engine (
#155
); the new Raycast node answers hit, object, collider, point, normal and distance in our own f64 geometry, the same in editor run and play, and the editor run draws each ray for 0.25 s (
#153
); On collision stay gains an interval with its own clock per pair, and stay and enter gain the contact point next to normal and impulse (
#149
); fixes that every Rapier collider of a tilemap had the shape of its last cell
2026-09-19 11:36:11 +02:00
42-shapes.mjs
The scene view outlines a tilemap's collision only along its outer edges: where two pieces meet, their shared stretch runs once in each direction and is not drawn, so an autotile lake is one outline without cross strokes at the quarters, merged rectangles of plain tiles and one-way tiles follow the same rule, the bridges from splitting concave outlines disappear and a piece doubled on two layers is outlined once; fill and collision stay as they were, and the result is cached per tilemap and rebuilt only when its collision data changes (
#173
)
2026-09-19 12:54:53 +02:00
43-queries.mjs
The one-way tolerance angle is a field: a one-way collider and a one-way tile gain One-way angle (0 to 90 degrees, default 45), a contact blocks when its normal is within that angle of the blocking side, without a value the limit is bit-identical to before, and the rule holds for Move, Raycast and dynamic bodies in Rapier; tiles with different angles never merge into one rectangle, the scene view draws the angle as a cone in the middle of the thick side, and the inspector shows Blocks from and One-way angle only while One-way is on, through the new schema option shownWith (
#159
)
2026-09-19 13:13:29 +02:00
44-documents.mjs
Open asset greyed out and real tab cards: Open asset in the scene object menu is only pickable for kinds with an editor of their own, the table of which asset opens which tab moved from Editor.ts into the new module assetTabs.ts with hasAssetEditor so the menu and the editor read the same list, Select asset stays as it was; tabs are drawn as index cards (new module TabButton.ts): the one showing is a light grey card instead of the aggressive blue, rounded above and square below, its name in plain weight and measured bold so it never clips itself, and a mouse down on the tab already showing keeps its colour; the padding left and right grew to 6 px in one place for both kinds of tab, Scene and Game carry an icon too (the scene one from the asset panel, a new game.svg play sign), Plugins and a plugin's own tab have none; new test hook menuEnabled next to menuRows and menuIcons, e2e 01 checks the greyed out entry on a sprite row, 14a-ii the card and the icons of the fixed tabs, 44a the icon at the wider padding (
#176
)
2026-09-20 11:40:01 +02:00
45-login.mjs
Changing the password: the Logout button at the far right of the toolbar became an Account menu that names the signed-in account in an entry of its own that cannot be picked, with Change password... above Logout, and the new dialog (src/editor/auth/PasswordDialog.ts) asks for the current password, the new one and its repetition, all three as bullets, and stays standing when the server refuses so that it can say why, unlike the other form dialogs; the rules for empty, too short, new equal to old and a differing repetition sit as the pure function passwordProblem() next to loginProblem(), the API gained POST ?r=auth/password which answers 204, insists on the current password although a session is there, enforces a minimum length of 8 in UserStore::MIN_PASSWORD_LENGTH and again in the client so the mask can answer without asking the server, and the new SessionStore::destroyAllFor($user, $keep) ends every other session of the account while the tab that changed the password keeps its own; the placeholders admin/admin and user/user stay as they are, which the length check does not touch because it only runs when a password is set through the API; e2e 45 grew by 8 checks for the menu, the dialog, both refusals and signing in with the old and the new password, and it sets the e2e account back at the end - a run dying in between leaves it on <password>-tmp, which a make-user.php call repairs (
#182
)
2026-09-20 13:46:40 +02:00
index.mjs
User management: signing in is required before anything is loaded, the sign-in screen is drawn in the same canvas (user name, password as bullets, Enter moves on and submits) and the editor is built only after it; the API gained auth/session, auth/login and auth/logout while every other route answers 401 without a session, projects carry an owner and a foreign one comes back as 404, accounts live in data/users.json with a password hash and sessions as files in data/sessions with a sliding 30 days, so a build under the open tab does not sign anybody out; Logout sits at the far right of the toolbar and, as asked in the issue, does not reload the page: Editor.dispose() takes the editor down while the canvas stays, which is why the autosave, the focus handlers, the window listeners of the tilemap panel, the shortcuts and the plugins all got a way back; the tools sign in as e2e (tools/lib/auth.mjs, password from GAME_MAKER_E2E_PASSWORD or the git-ignored data/e2e-password.txt) and the browser gets the same session by cookie, new e2e module 45 covers the screen, the wrong pair, the bullets, logout without a reload and signing in again, new unit tests for HttpAuthStore and for what a session leaves behind (
#177
)
2026-09-20 12:50:52 +02:00