@bongos/core 1.24.72 → 1.24.74
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/.bongos-core.json +107 -77
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +2 -0
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/api/openapi.json +36 -2
- package/docs/api-reference.md +3 -2
- package/docs/copy-inventory.md +5 -5
- package/docs/copy-registry.json +5 -5
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +33 -0
- package/docs/page-readings.json +33 -33
- package/modules/government/board.js +19 -7
- package/modules/government/config.js +21 -9
- package/modules/government/constitution.js +224 -0
- package/modules/government/db.js +28 -0
- package/modules/government/migrations/government_037_constitution.sql +33 -0
- package/modules/government/module.json +2 -1
- package/modules/government/pollers/constitution-restore.js +45 -0
- package/modules/government/routes/government.js +7 -7
- package/modules/hall-ui/public/ai-studio.html +2 -1
- package/modules/hall-ui/public/atlas.html +2 -1
- package/modules/hall-ui/public/blockers.html +2 -1
- package/modules/hall-ui/public/board-room.html +2 -1
- package/modules/hall-ui/public/board-room.js +7 -3
- package/modules/hall-ui/public/city.html +2 -1
- package/modules/hall-ui/public/collab.html +2 -1
- package/modules/hall-ui/public/commands.html +2 -1
- package/modules/hall-ui/public/copy-desk.html +2 -1
- package/modules/hall-ui/public/deploy.html +2 -1
- package/modules/hall-ui/public/goal-map.html +2 -1
- package/modules/hall-ui/public/goals.html +2 -1
- package/modules/hall-ui/public/government.html +2 -1
- package/modules/hall-ui/public/idea.html +2 -1
- package/modules/hall-ui/public/ideas.html +2 -1
- package/modules/hall-ui/public/index.html +2 -1
- package/modules/hall-ui/public/market-watch-item.html +2 -1
- package/modules/hall-ui/public/market-watch-rules.html +2 -1
- package/modules/hall-ui/public/market-watch.html +2 -1
- package/modules/hall-ui/public/modules.html +2 -1
- package/modules/hall-ui/public/money.html +2 -1
- package/modules/hall-ui/public/my-agents.html +2 -1
- package/modules/hall-ui/public/primer.html +2 -1
- package/modules/hall-ui/public/profile.html +2 -1
- package/modules/hall-ui/public/project-settings.html +2 -1
- package/modules/hall-ui/public/roster.html +2 -1
- package/modules/hall-ui/public/settings.html +2 -1
- package/modules/hall-ui/public/shell-game.js +50 -0
- package/modules/hall-ui/public/shell.js +11 -11
- package/modules/hall-ui/public/street-card.js +2 -0
- package/modules/hall-ui/public/street.html +2 -1
- package/modules/hall-ui/public/studio.html +2 -1
- package/modules/hall-ui/public/task.html +2 -1
- package/modules/hall-ui/public/thinking.html +2 -1
- package/modules/hall-ui/public/tweak-editor.html +2 -1
- package/modules/hall-ui/public/watch.html +2 -1
- package/modules/hall-ui/public/work.html +2 -1
- package/modules/hall-ui/records/game-mode.md +20 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/scripts/bongos/government-walk.js +7 -0
- package/src/bongos/route-rank-check.js +4 -0
- package/src/module-api.js +1 -1
- package/tests/genesis_government.mjs +11 -0
- package/tests/goal_map_page.mjs +2 -2
- package/tests/government_board_amendment.mjs +10 -0
- package/tests/government_charter_forms.mjs +10 -0
- package/tests/government_constitution_durable.mjs +304 -0
- package/tests/government_seed.mjs +1 -0
- package/tests/hall_city.mjs +1 -1
- package/tests/hall_fullscreen.mjs +101 -0
- package/tests/hall_my_agents.mjs +1 -1
- package/tests/hall_street.mjs +1 -1
- package/tests/nav_permission_atoms.mjs +1 -1
package/modules/government/db.js
CHANGED
|
@@ -1320,7 +1320,35 @@ async function insertVoteKarma({ voterId, itemId, delta }) {
|
|
|
1320
1320
|
);
|
|
1321
1321
|
}
|
|
1322
1322
|
|
|
1323
|
+
// ── the constitution in force (task 1005140) ─────────────────────────────────
|
|
1324
|
+
// ONE row (government_037). The board block is stored exactly as sanitizeBoard
|
|
1325
|
+
// returns it; constitution.js owns the rules for when it is written and how the
|
|
1326
|
+
// running process is brought in step with it. `q` is a client or the pool.
|
|
1327
|
+
async function getConstitutionRow(q = pool) {
|
|
1328
|
+
const { rows } = await q.query(
|
|
1329
|
+
`SELECT board, source, amendment_item_id, updated_by, updated_at
|
|
1330
|
+
FROM government_constitution WHERE id = 1`,
|
|
1331
|
+
);
|
|
1332
|
+
return rows[0] || null;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
async function saveConstitutionRow({ board, source, itemId = null, updatedBy = null } = {}, q = pool) {
|
|
1336
|
+
const { rows } = await q.query(
|
|
1337
|
+
`INSERT INTO government_constitution (id, board, source, amendment_item_id, updated_by, updated_at)
|
|
1338
|
+
VALUES (1, $1::jsonb, $2, $3, $4, now())
|
|
1339
|
+
ON CONFLICT (id) DO UPDATE
|
|
1340
|
+
SET board = EXCLUDED.board, source = EXCLUDED.source,
|
|
1341
|
+
amendment_item_id = EXCLUDED.amendment_item_id,
|
|
1342
|
+
updated_by = EXCLUDED.updated_by, updated_at = now()
|
|
1343
|
+
RETURNING board, source, amendment_item_id, updated_by, updated_at`,
|
|
1344
|
+
[JSON.stringify(board), source, itemId, updatedBy],
|
|
1345
|
+
);
|
|
1346
|
+
return rows[0] || null;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1323
1349
|
module.exports = {
|
|
1350
|
+
getConstitutionRow,
|
|
1351
|
+
saveConstitutionRow,
|
|
1324
1352
|
openBoardItemsAwaitingVoter,
|
|
1325
1353
|
getTaskStatuses,
|
|
1326
1354
|
listLatestGenesisStageItems,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-- government_037_constitution.sql — the constitution in force is a ROW (task 1005140).
|
|
2
|
+
--
|
|
3
|
+
-- WHY
|
|
4
|
+
--
|
|
5
|
+
-- A ratified amendment used to live only in <instance root>/config/government.json.
|
|
6
|
+
-- Every instance this platform provisions runs on a container whose filesystem is
|
|
7
|
+
-- wiped on each deploy, restart and idle wake, so the board's decision was written,
|
|
8
|
+
-- took effect, and vanished at the next container start. The project went back to
|
|
9
|
+
-- the day-one monarchy without an error (found live on toast, 2026-11-07).
|
|
10
|
+
--
|
|
11
|
+
-- WHAT THIS ADDS
|
|
12
|
+
--
|
|
13
|
+
-- government_constitution — at most ONE row (id = 1): the instance's board block,
|
|
14
|
+
-- exactly as sanitizeBoard (modules/government/config.js) would write it. The four
|
|
15
|
+
-- keys are the whole block; nothing else rides here (rank templates stay config).
|
|
16
|
+
-- `source` says how the row got here: a passed amendment, a file adopted on first
|
|
17
|
+
-- read, or an operator re-applying the newest passed amendment.
|
|
18
|
+
--
|
|
19
|
+
-- It is NOT authority: the block names which RANK governs; who holds that rank is
|
|
20
|
+
-- still a government_builder_ranks row, resolved per request.
|
|
21
|
+
|
|
22
|
+
BEGIN;
|
|
23
|
+
|
|
24
|
+
CREATE TABLE IF NOT EXISTS government_constitution (
|
|
25
|
+
id smallint PRIMARY KEY DEFAULT 1 CHECK (id = 1),
|
|
26
|
+
board jsonb NOT NULL CHECK (jsonb_typeof(board) = 'object'),
|
|
27
|
+
source text NOT NULL CHECK (source IN ('amendment', 'adopted_file', 'reapply')),
|
|
28
|
+
amendment_item_id bigint REFERENCES government_board_items(id) ON DELETE SET NULL,
|
|
29
|
+
updated_by bigint REFERENCES builders(id) ON DELETE SET NULL,
|
|
30
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
COMMIT;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// modules/government/pollers/constitution-restore.js — the constitution in force
|
|
4
|
+
// comes back after a restart (task 1005140).
|
|
5
|
+
//
|
|
6
|
+
// A provisioned instance boots on a fresh container: the file the running
|
|
7
|
+
// process reads its constitution from is gone, and without this the project
|
|
8
|
+
// silently answers the day-one monarchy until somebody notices. So the FIRST
|
|
9
|
+
// reconcile runs as soon as the poller starts, not after a delay — every moment
|
|
10
|
+
// before it is a moment the wrong rule is in force. After that it re-checks on a
|
|
11
|
+
// slow interval, which also keeps a second process in step with an amendment
|
|
12
|
+
// another one applied.
|
|
13
|
+
//
|
|
14
|
+
// Quiet when in step; one line when it restores or adopts (constitution.js).
|
|
15
|
+
|
|
16
|
+
const api = require('../../../src/module-api');
|
|
17
|
+
const constitution = require('../constitution');
|
|
18
|
+
|
|
19
|
+
const logger = api.logger('government');
|
|
20
|
+
|
|
21
|
+
const INTERVAL_MS = Number(process.env.CONSTITUTION_RESTORE_SWEEP_MS) || 5 * 60_000;
|
|
22
|
+
|
|
23
|
+
let intervalTimer = null;
|
|
24
|
+
|
|
25
|
+
function start({ reconcileFn = constitution.reconcile } = {}) {
|
|
26
|
+
if (process.env.CONSTITUTION_RESTORE_DISABLED === '1') {
|
|
27
|
+
logger.info('[constitution-restore] disabled (CONSTITUTION_RESTORE_DISABLED=1)');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (intervalTimer) return;
|
|
31
|
+
const tick = () => {
|
|
32
|
+
Promise.resolve()
|
|
33
|
+
.then(() => reconcileFn({ log: (m) => logger.info(m), error: (m) => logger.error(m) }))
|
|
34
|
+
.catch((e) => logger.error(`[constitution-restore] reconcile crashed: ${e && e.message}`));
|
|
35
|
+
};
|
|
36
|
+
tick();
|
|
37
|
+
intervalTimer = setInterval(tick, INTERVAL_MS);
|
|
38
|
+
if (intervalTimer.unref) intervalTimer.unref();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function stop() {
|
|
42
|
+
if (intervalTimer) { clearInterval(intervalTimer); intervalTimer = null; }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { start, stop, INTERVAL_MS };
|
|
@@ -36,6 +36,7 @@ const asksDb = require('../asks-db');
|
|
|
36
36
|
const routing = require('../routing');
|
|
37
37
|
const { accessHandlers } = require('../access-routes');
|
|
38
38
|
const governmentConfig = require('../config');
|
|
39
|
+
const constitution = require('../constitution');
|
|
39
40
|
const membershipPredicate = require('../membership-predicate');
|
|
40
41
|
const positions = require('../positions');
|
|
41
42
|
const decisionBoard = require('../decision-board');
|
|
@@ -724,8 +725,7 @@ module.exports = function buildGovernmentRouter() {
|
|
|
724
725
|
// the live board block plus the full amendment history, passed and returned
|
|
725
726
|
// alike. Same atom as the room — reading the rule you vote under is part of
|
|
726
727
|
// casting, and the section teaches (criterion C5). The live value resolves
|
|
727
|
-
// fresh per request, so an amendment applied a moment ago reads back
|
|
728
|
-
// immediately (the same instant-effect posture as everything else here).
|
|
728
|
+
// fresh per request, so an amendment applied a moment ago reads back at once.
|
|
729
729
|
router.get('/government/constitution', api.requireBuilder, api.requirePermission('board.vote.cast'), async (req, res) => {
|
|
730
730
|
try {
|
|
731
731
|
// ?type= and ?headcount= ask about another project type or size (task
|
|
@@ -741,6 +741,9 @@ module.exports = function buildGovernmentRouter() {
|
|
|
741
741
|
}
|
|
742
742
|
});
|
|
743
743
|
|
|
744
|
+
// rank: perm government.manage — re-apply the newest PASSED amendment (task 1005140; constitution.js).
|
|
745
|
+
router.post('/government/constitution/reapply', api.requireBuilder, api.requirePermission('government.manage'), constitution.reapplyRoute(log));
|
|
746
|
+
|
|
744
747
|
// rank: perm board.vote.cast — the founding band's read (task 1004429): each
|
|
745
748
|
// genesis stage's latest sitting, and who it is still waiting on under the
|
|
746
749
|
// item's own snapshot. Same atom as the room — seeing who is still to vote is
|
|
@@ -1454,11 +1457,7 @@ module.exports = function buildGovernmentRouter() {
|
|
|
1454
1457
|
const status =
|
|
1455
1458
|
out.reason === 'item_not_found' ? 404 :
|
|
1456
1459
|
out.reason === 'not_board_member' ? 403 :
|
|
1457
|
-
// 'anti_self_vote' was retired by task 1003273
|
|
1458
|
-
// what they cannot do is decide alone, which the close trigger and the
|
|
1459
|
-
// tally enforce rather than the route. The mapping is left OUT rather
|
|
1460
|
-
// than kept "just in case": a reason castVote can no longer return
|
|
1461
|
-
// would be dead code pretending to be a wall.
|
|
1460
|
+
// 'anti_self_vote' was retired by task 1003273 (an author may cast, never decide alone) — left OUT on purpose.
|
|
1462
1461
|
|
|
1463
1462
|
out.reason === 'item_closed' ? 409 :
|
|
1464
1463
|
out.reason === 'vote_window_expired' ? 409 :
|
|
@@ -1486,6 +1485,7 @@ module.exports = function buildGovernmentRouter() {
|
|
|
1486
1485
|
already_voted: !out.fresh,
|
|
1487
1486
|
...(out.fresh ? { karma_delta: out.karma_delta } : {}),
|
|
1488
1487
|
...(closure && closure.closed ? { item_closed: true, outcome: closure.outcome } : {}),
|
|
1488
|
+
...(closure && closure.constitution_not_applied ? { constitution_not_applied: closure.constitution_not_applied } : {}),
|
|
1489
1489
|
});
|
|
1490
1490
|
} catch (err) {
|
|
1491
1491
|
log.error('[gds] POST /government/board/items/:itemId/votes', err);
|
|
@@ -87,9 +87,10 @@
|
|
|
87
87
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
88
88
|
|
|
89
89
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
90
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
90
91
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
91
92
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
92
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
93
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
93
94
|
<script src="/builders/hall-dialog.js"></script>
|
|
94
95
|
<script src="/builders/palette.js" defer></script>
|
|
95
96
|
<script src="/builders/tweak-editor-lib.js?v=2026-09-28-tw23"></script>
|
|
@@ -90,9 +90,10 @@
|
|
|
90
90
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
91
91
|
|
|
92
92
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
93
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
93
94
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
94
95
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
95
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
96
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
96
97
|
<script src="/builders/hall-dialog.js"></script>
|
|
97
98
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
98
99
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -59,9 +59,10 @@
|
|
|
59
59
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
60
60
|
chrome exists before the page script runs. -->
|
|
61
61
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
62
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
62
63
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
63
64
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
64
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
65
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
65
66
|
<script src="/builders/hall-dialog.js"></script>
|
|
66
67
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
67
68
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -61,9 +61,10 @@
|
|
|
61
61
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
62
62
|
|
|
63
63
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
64
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
64
65
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
65
66
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
66
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
67
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
67
68
|
<script src="/builders/hall-dialog.js"></script>
|
|
68
69
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
69
70
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -415,9 +415,13 @@
|
|
|
415
415
|
}
|
|
416
416
|
try {
|
|
417
417
|
const out = await sendJson('POST', `/government/board/items/${encodeURIComponent(itemId)}/votes`, body);
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
// Task 1005140: a ratified change that did not take is said now, loudly,
|
|
419
|
+
// not weeks later in the Constitution tab's warning.
|
|
420
|
+
toast(out.constitution_not_applied
|
|
421
|
+
? 'Passed, but the new constitution did not take effect. The old rules are still in force; the owner can re-apply it.'
|
|
422
|
+
: out.item_closed
|
|
423
|
+
? `Vote cast — the sitting closed: ${out.outcome}.`
|
|
424
|
+
: 'Vote cast.');
|
|
421
425
|
} catch (err) {
|
|
422
426
|
if (err && err.kind === '401') return;
|
|
423
427
|
toast(`Could not vote: ${err.message || err}`);
|
|
@@ -106,9 +106,10 @@
|
|
|
106
106
|
</div>
|
|
107
107
|
|
|
108
108
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
109
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode" defer></script>
|
|
109
110
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers" defer></script>
|
|
110
111
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals" defer></script>
|
|
111
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
112
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode" defer></script>
|
|
112
113
|
<script src="/builders/hall-dialog.js" defer></script>
|
|
113
114
|
<script src="/builders/palette.js" defer></script>
|
|
114
115
|
<script src="/builders/gov-living.js?v=2026-10-09-positions1" defer></script>
|
|
@@ -160,9 +160,10 @@
|
|
|
160
160
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
161
161
|
|
|
162
162
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
163
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
163
164
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
164
165
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
165
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
166
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
166
167
|
<script src="/builders/hall-dialog.js"></script>
|
|
167
168
|
<script src="/builders/palette.js" defer></script>
|
|
168
169
|
<script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
|
|
@@ -52,9 +52,10 @@
|
|
|
52
52
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
53
53
|
|
|
54
54
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
55
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
55
56
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
56
57
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
57
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
58
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
58
59
|
<script src="/builders/hall-dialog.js"></script>
|
|
59
60
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
60
61
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -178,9 +178,10 @@
|
|
|
178
178
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
179
179
|
|
|
180
180
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
181
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
181
182
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
182
183
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
183
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
184
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
184
185
|
<script src="/builders/hall-dialog.js"></script>
|
|
185
186
|
<script src="/builders/palette.js" defer></script>
|
|
186
187
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -79,9 +79,10 @@
|
|
|
79
79
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
80
80
|
|
|
81
81
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
82
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
82
83
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
83
84
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
84
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
85
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
85
86
|
<script src="/builders/hall-dialog.js"></script>
|
|
86
87
|
<script src="/builders/palette.js" defer></script>
|
|
87
88
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -138,9 +138,10 @@
|
|
|
138
138
|
</div>
|
|
139
139
|
|
|
140
140
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
141
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
141
142
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
142
143
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
143
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
144
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
144
145
|
<script src="/builders/hall-dialog.js"></script>
|
|
145
146
|
<script src="/builders/palette.js" defer></script>
|
|
146
147
|
|
|
@@ -251,9 +251,10 @@
|
|
|
251
251
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
252
252
|
|
|
253
253
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
254
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
254
255
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
255
256
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
256
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
257
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
257
258
|
<script src="/builders/hall-dialog.js"></script>
|
|
258
259
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
259
260
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -155,9 +155,10 @@
|
|
|
155
155
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
156
156
|
|
|
157
157
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
158
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
158
159
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
159
160
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
160
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
161
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
161
162
|
<script src="/builders/hall-dialog.js"></script>
|
|
162
163
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
163
164
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -51,9 +51,10 @@
|
|
|
51
51
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
52
52
|
|
|
53
53
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
54
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
54
55
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
55
56
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
56
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
57
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
57
58
|
<script src="/builders/hall-dialog.js"></script>
|
|
58
59
|
<script src="/builders/palette.js" defer></script>
|
|
59
60
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N overlay, so a ref
|
|
@@ -226,9 +226,10 @@
|
|
|
226
226
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
227
227
|
|
|
228
228
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
229
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
229
230
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
230
231
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
231
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
232
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
232
233
|
<script src="/builders/hall-dialog.js"></script>
|
|
233
234
|
<script src="/builders/palette.js" defer></script>
|
|
234
235
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -107,9 +107,10 @@
|
|
|
107
107
|
<!-- task 1004785: the first-visit-of-the-day welcome (the tower). Before shell.js, which asks it
|
|
108
108
|
before the craft picker so the two never stack. Home only. -->
|
|
109
109
|
<script src="/builders/welcome-boot.js?v=2026-11-07-brand-mark" defer></script>
|
|
110
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode" defer></script>
|
|
110
111
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers" defer></script>
|
|
111
112
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals" defer></script>
|
|
112
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
113
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode" defer></script>
|
|
113
114
|
<script src="/builders/hall-dialog.js" defer></script>
|
|
114
115
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
115
116
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -72,9 +72,10 @@
|
|
|
72
72
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
73
73
|
|
|
74
74
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
75
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
75
76
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
76
77
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
77
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
78
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
78
79
|
<script src="/builders/hall-dialog.js"></script>
|
|
79
80
|
<script src="/builders/palette.js" defer></script>
|
|
80
81
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -41,9 +41,10 @@
|
|
|
41
41
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
42
42
|
|
|
43
43
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
44
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
44
45
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
45
46
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
46
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
47
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
47
48
|
<script src="/builders/hall-dialog.js"></script>
|
|
48
49
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
49
50
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -186,9 +186,10 @@
|
|
|
186
186
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
187
187
|
|
|
188
188
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
189
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
189
190
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
190
191
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
191
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
192
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
192
193
|
<script src="/builders/hall-dialog.js"></script>
|
|
193
194
|
<script src="/builders/palette.js" defer></script>
|
|
194
195
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -126,9 +126,10 @@
|
|
|
126
126
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
127
127
|
|
|
128
128
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
129
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
129
130
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
130
131
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
131
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
132
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
132
133
|
<script src="/builders/hall-dialog.js"></script>
|
|
133
134
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
134
135
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -80,9 +80,10 @@
|
|
|
80
80
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
81
81
|
|
|
82
82
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
83
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
83
84
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
84
85
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
85
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
86
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
86
87
|
<script src="/builders/hall-dialog.js"></script>
|
|
87
88
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
88
89
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -82,9 +82,10 @@
|
|
|
82
82
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
83
83
|
|
|
84
84
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
85
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
85
86
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
86
87
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
87
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
88
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
88
89
|
<script src="/builders/hall-dialog.js"></script>
|
|
89
90
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
90
91
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -111,9 +111,10 @@
|
|
|
111
111
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
112
112
|
|
|
113
113
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
114
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
114
115
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
115
116
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
116
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
117
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
117
118
|
<script src="/builders/hall-dialog.js"></script>
|
|
118
119
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
119
120
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -247,9 +247,10 @@
|
|
|
247
247
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
248
248
|
chrome exists before the page script runs. -->
|
|
249
249
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
250
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
250
251
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
251
252
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
252
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
253
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
253
254
|
<script src="/builders/hall-dialog.js"></script>
|
|
254
255
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
255
256
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -75,9 +75,10 @@
|
|
|
75
75
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
76
76
|
|
|
77
77
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
78
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
78
79
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
79
80
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
80
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
81
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
81
82
|
<script src="/builders/hall-dialog.js"></script>
|
|
82
83
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
83
84
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -57,9 +57,10 @@
|
|
|
57
57
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
58
58
|
chrome exists before the page script runs. -->
|
|
59
59
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
60
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
60
61
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
61
62
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
62
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
63
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
63
64
|
<script src="/builders/hall-dialog.js"></script>
|
|
64
65
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
65
66
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -392,9 +392,10 @@
|
|
|
392
392
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
393
393
|
chrome exists before the page scripts run. -->
|
|
394
394
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
395
|
+
<script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
|
|
395
396
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
396
397
|
<script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
|
|
397
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
398
|
+
<script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
|
|
398
399
|
<script src="/builders/hall-dialog.js"></script>
|
|
399
400
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
400
401
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// shell-game.js — game mode: the hall-wide half of the shell's full-screen switch
|
|
2
|
+
// (task 1005142, BONGOS-V3 R02, goal 1000141; docs/specs/bongos-v3-game-conversion.md
|
|
3
|
+
// §Reuse, do not rebuild). The switch itself is shell.js's and stays there: this
|
|
4
|
+
// file only answers ONE question for it — is the hall in game mode? — and when it
|
|
5
|
+
// is, every page opens in full screen (no sidebar, no top bar, no foot) whatever
|
|
6
|
+
// that page remembers on its own. Nothing here hides anything: shell.js does, with
|
|
7
|
+
// the same html[data-fullscreen="on"] state, the same corner button and the same
|
|
8
|
+
// Escape hand-off (a page listener that calls preventDefault keeps the press).
|
|
9
|
+
//
|
|
10
|
+
// The mode is one localStorage key (`hall-game`), so it follows the browser across
|
|
11
|
+
// every hall page, and one attribute, html[data-game="on"], for a sheet or script
|
|
12
|
+
// that wants to read it. Leaving full screen in game mode (the button, Escape)
|
|
13
|
+
// brings the bars back for THAT page load only: the next page opens without them
|
|
14
|
+
// again, and a page's own remembered choice is never overwritten. `?game=on` /
|
|
15
|
+
// `?game=off` on any hall URL sets it by hand until the start screen does (R03).
|
|
16
|
+
// Loaded BEFORE shell.js on every hall page; a page without this file is simply
|
|
17
|
+
// never in game mode.
|
|
18
|
+
(function () {
|
|
19
|
+
'use strict';
|
|
20
|
+
var KEY = 'hall-game';
|
|
21
|
+
var HINT_KEY = 'hall-game-hint';
|
|
22
|
+
function read(store, key) { try { return window[store].getItem(key); } catch (_) { return null; } }
|
|
23
|
+
function write(store, key, value) { try { window[store].setItem(key, value); } catch (_) { /* private mode */ } }
|
|
24
|
+
function on() { return read('localStorage', KEY) === 'on'; }
|
|
25
|
+
function stamp() {
|
|
26
|
+
var root = document.documentElement;
|
|
27
|
+
if (on()) root.dataset.game = 'on'; else delete root.dataset.game;
|
|
28
|
+
}
|
|
29
|
+
// Turn the mode on or off, and have the shell show what this page should now show.
|
|
30
|
+
function set(value) {
|
|
31
|
+
write('localStorage', KEY, value ? 'on' : 'off');
|
|
32
|
+
stamp();
|
|
33
|
+
if (window.OTBShell && window.OTBShell.setFullscreen) window.OTBShell.setFullscreen(null);
|
|
34
|
+
}
|
|
35
|
+
// Whether the shell should say how to leave full screen. Outside game mode,
|
|
36
|
+
// always (its own rule); inside it, once per tab — every page opens in full
|
|
37
|
+
// screen there, and the same sentence on every page load is noise.
|
|
38
|
+
function hint() {
|
|
39
|
+
if (!on()) return true;
|
|
40
|
+
if (read('sessionStorage', HINT_KEY)) return false;
|
|
41
|
+
write('sessionStorage', HINT_KEY, '1');
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
var asked = new URLSearchParams(window.location.search || '').get('game');
|
|
46
|
+
if (asked === 'on' || asked === 'off') write('localStorage', KEY, asked);
|
|
47
|
+
} catch (_) { /* old engine: the stored value stands */ }
|
|
48
|
+
stamp();
|
|
49
|
+
window.OTBShellGame = { on: on, set: set, hint: hint };
|
|
50
|
+
})();
|